Ansible is great, it’s one of my favorite tools. It works like a charm, but… it requires SSH connection to the target host, which can be a problem in some high security environments, like the ones where SSH on the host is not allowed or the ones that work in VPCs without external connectivity.

However, in AWS, there’s a feature of AWS Systems Manager service called Sessions Manager. It works in the way that you install a special agent service on your instance and the agent allows you to establish the session to the instance from AWS Console or using AWS CLI.

The second option (with a special plugin) enables you even to establish… a ssh session but without direct connectivity to the host – the session will be “tunneled” through AWS SSM Sessions. Not only it allows you to connect from any place to any host with the agent (and with the help of VPC Endpoint you can reach even instances without external connectivity), but also offers IAM-based permission model, as well as audit logs for the connections.

The best thing is that you can combine AWS SSM Sessions with Ansible and execute existing playbooks on the instance, skipping traditional direct SSH connection. How to do that? Let me show you :)

Prepare EC2 Instance

There’re two things needed in order to enable SSM Agent. In my example I use CentOS host, but you can find manuals for most popular systems in AWS Docs.

First, ensure that the IAM Instance Profile of your instance has AmazonSSMManagedInstanceCore policy attached.

After that install SSM Agent package:

yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm

In production environment you probably want to burn that package inside your AMI and enable it on startup.

After installing the agent, you can go to AWS Console to ensure that AWS SSM can see your instance. You can also do that from AWS CLI:

aws ssm describe-instance-information

In order to use SSH client, the instance has to run SSH server, but you can restrict access to it on security group level or host firewall.

Prepare client host

On client host you need AWS CLI:

pip install awscli

…and an addon for Session Manager, the sample below is for Ubuntu on Windows Subsystem for Linux:

curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/ubuntu_64bit/session-manager-plugin.deb" -o "session-manager-plugin.deb" sudo dpkg -i session-manager-plugin.deb

After that, you’re ready to create Ansible inventory file, putting your instance id as a host address and adding some common settings to establish a proxy using AWS SSM Sessions:

my-instance ansible_host=i-08d7014e67aasdf56a [all:vars] ansible_ssh_common_args=-o StrictHostKeyChecking=no -o ProxyCommand="sh -c \"aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'\"" ansible_user='centos' ansible_become=true ansible_ssh_private_key_file='~/.ssh/management'

Please ensure that you use valid SSH key – yes, it’s needed, but as you can use shared keys for your hosts, because you restrict access to ssh using IAM policies for AWS SSM.

When everything is ready, just ping the instance to check connectivity:

ansible all -i ssm-inventory -m ping

Now, you’re ready to run your playbooks :)

Controlling access to instances

As I mentioned before, you can limit access to specific instances for specific users, you also can limit based on tags, which is quite powerful idea – here’s the sample from AWS Docs:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ssm:StartSession" ], "Resource": [ "arn:aws:ec2:*:*:instance/*" ], "Condition": { "StringLike": { "ssm:resourceTag/Finance": [ "WebServers" ] } } }, { "Effect": "Allow", "Action": [ "ssm:TerminateSession" ], "Resource": [ "arn:aws:ssm:*:*:session/${aws:username}-*" ] } ] }

You can find more about IAM security for SSM Sessions Manager here.

Summary

As you can see above, the SSM Sessions Manager is quick to setup, easy to use and very powerful. With just a few steps you’re able to run your existing Ansible playbooks on the hosts, all it takes is a little modification in an inventory file.

I’m very curious about what you think about it and about your experiences – please share them in the comments :)