Ansible Amenities: Dynamic Host Groups with Jinja template data processing
Demo for list-repos -- Pankaj Patel @ unsplash
At work, I’ve been steadily improving our automation. It’s not always guaranteed that our servers are set up uniformly nor are they always tagged the right way.
For the ones that we can get at, it’s sometimes easier to use Ansibles ansible.builtin.add_host.
Queries
We use AWS. Grabbing existing hosts from EC2 is pretty easy:
- name: Query AWS for EC2 Instances
amazon.aws.ec2_instance_info:
filters:
"tag:Name": "{{ instance_name }}"
"instance-state-name": "running"
register: new_instance_query_result
Massaging the Data
AWS’ amazon.aws.ec2_instance_info return values come back fairly complex, we can’t just throw the results into add_host and be done, let’s make it a little more palatable first:
- name: Create Data Dict from instances query
ansible.builtin.set_fact:
new_instance_data: >
{{ new_instance_query_result.results
| json_query('[].instances[]')
| list
| json_query('[].{ id: instance_id, name: tags.Name, private_dns: private_dns_name, ip: private_ip_address}')
| to_json
| from_json }}
This should give you a data structure like this:
[
{
"id": "i-abcdef",
"name": "my-host",
"private_dns": "abc-def.aws.local"
"ip": "127.0.0.1"
},
{
...
}
]
Host Groups
With out data cleaned up and simplified we can use add_host finally to create our hostgroup:
- name: "Create Host List to deploy to"
ansible.builtin.add_host:
name: '{{ instance.name }}'
hostname: '{{ instance.privte_dns }}'
ansible_ssh_host: '{{ instance.ip }}'
group:
- DeployHosts
loop: "{{ new_instance_data }}"
loop_control:
loop_var: instance
Use it!
Now we can use the DeployHosts collection as our host to connect to and deploy our configuration!
- name: Get server Details
gather_facts: false
become: false
hosts: DeployHosts
tasks:
- ...
Closing Words
Ansible’s templates and data processing is very powerful if used correctly. This is all thanks to Jinja and the filters features. Use it wisely and it will elevate your playbook writing to the next level.
Hope this helped!