Dynamic inventory Ansible (behind a jumpbox / bastion )

James Kingsmill
Feb 12, 2017 · 2 min read

The problem: you want to deploy code to an AutoScaling Group, but the EC2 instances are in a security group that is only accessible through a jumpbox.

Dynamic inventory

Step one is to get Ansible working with dynamic inventory. (We assume you’ve installed Ansible already.)

Download ec2.py and ec2.ini and put them both in /etc/ansible/. (If you’re on a Mac you’ll need to create this directory.)

cd /etc/ansiblesudo wget https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.pysudo wget https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.ini

Then set environment variables to point Ansible to the right locations:

export ANSIBLE_HOSTS=/etc/ansible/ec2.py
export EC2_INI_PATH=/etc/ansible/ec2.ini

If your AWS credentials have been set, you should be able to list your inventory:

python /etc/ansible/ec2.py --list

Make sure your ssh keypair has been added to your ssh-agent:

ssh-add ~/.ssh/keypair

And from there, you should be able to run Ansible against one of your instances. In this case, there’s an EC2 instance that was tagged with Name: testbox.

ansible -m ping “tag_Name_testbox”
10.0.12.34 | SUCCESS => {
“changed”: false,
“ping”: “pong”
}

Jumpbox

The next step is to get Ansible working with instances that are only ssh accessible through a jumpbox.

Make the following changes to /etc/ansible/ec2.ini to ensure Ansible connects on the EC2 instances’ private IPs:

destination_variable = private_dns_name
vpc_destination_variable = private_ip_address

Add the following lines to ~/.ssh/config. This will forward all ssh connections to anything within your VPC on the 10.0.0.0/16 subnet through your jumphost’s public IP (13.50.123.45 in this case).

Host 10.*.*.*
User ubuntu
IdentityFile ~/.ssh/keypair
ProxyCommand ssh -q -W %h:%p 13.50.123.45 #-q only required on Mac
Host 13.50.123.45
User ubuntu
IdentityFile ~/.ssh/keypair
ForwardAgent yes

Add these lines to a file called playbook.yml:

---
- hosts: tag_Name_testbox
remote_user: ubuntu
become: yes
tasks:
- name: test connection
ping:
remote_user: ubuntu

When you run ansible-playbook on this file, you should get a positive response from your tagged instance:

ansible-playbook playbook.yml
PLAY [tag_Name_testbox] ************************************************
TASK [setup] *******************************************************************
ok: [10.0.12.34]
---
TASK [test connection] *********************************************************
ok: [10.0.12.34]
PLAY RECAP *********************************************************************
10.0.12.34 : ok=2 changed=0 unreachable=0 failed=0

(If you get a /usr/bin/python error, make sure that you have python installed on the managed node as per the Ansible install guide.)

It’s a short jump to get this integrated into your deployment pipeline!

Links

http://docs.ansible.com/ansible/intro_dynamic_inventory.html

https://aws.amazon.com/blogs/apn/getting-started-with-ansible-and-dynamic-amazon-ec2-inventory-management/

http://blog.scottlowe.org/2015/12/24/running-ansible-through-ssh-bastion-host/

James Kingsmill

Written by

Cloud/Culture/DevOps

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade