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 :)
AWS : Communiquer avec vos EC2 sans réseau - La liberté du design d'architecture sans contraintes - EASYTEAM Apr 22 , 2020 at 08:01 /
[…] Des outils nécessitant l’utilisation de ssh peuvent avoir recours à ce stratagème. Cf. https://luktom.net/en/e1693-ansible-over-aws-systems-manager-sessions-a-perfect-solution-for-high-s… […]
Bill May 09 , 2021 at 09:43 /
Can ansible connect to the instance through session manager without using keys similar to connecting with the AWS CLI without keys?
luktom May 13 , 2021 at 22:12 /
There’s a community plugin for that:
https://docs.ansible.com/ansible/latest/collections/community/aws/aws_ssm_connection.html
However I haven’t tested it yet, but let me know if you try it :)
peter Aug 13 , 2021 at 21:50 /
when running ansile ping command, it is asking me to specify the region. how did overcame this error ?
thanks
Paul Feb 04 , 2022 at 13:45 /
@Peter : simply add the option –region $YOUR_REGION_HERE into the ansible hosts file. You can add it as the last option, after the port number one
Wc Mar 24 , 2022 at 08:40 /
If you generate the ssh key locally, please remember to add your public key to the instance.
Joe May 13 , 2022 at 02:55 /
I want to connect AWS Systems manager to AWX, do you have any knowledge on that?
luktom May 15 , 2022 at 11:52 /
Hi Joe, you can easily use AWS SSM from AWX, the only important point here is that you need to provide instance profile with proper IAM policy for EC2 hosting AWX – this way scripts running on AWX will be able to execute AWS API commands.
vj Aug 22 , 2022 at 21:29 /
how to test a windows over aws_ssm