I have a playbook for creating some EC2 instances and then doing some stuff with them. The relevant pieces are approximately like:
- name: create ec2 instances
ec2:
id: '{{ item.name }}'
instance_type: '{{ item.type }}'
register: ec2
with_items: '{{ my_instance_defs }}'
- name: wait for SSH
wait_for:
host: '{{ item.instances[0].private_ip }}'
port: 22
with_items: '{{ ec2.results }}'
This works as intended, but I am not especially happy with the item.instances[0].private_ip
expression, partly because it shows really large objects in the play summary. I would love to have the with_items
part just be an array of IP addresses, rather than an array of objects with arrays of objects inside them. In Python, I would just do something like:
ips = [r['instances'][0]['private_ip'] for r in ec2['results']]
And then I would use with_items: '{{ ips }}'
in the second task.
Is there a way I can do the same thing using a J2 filter in the YAML of the play? Seems like http://docs.ansible.com/ansible/playbooks_filters.html#extracting-values-from-containers might be helpful, but I think that presupposes I have an array of keys/indices/whatever.
So if you want to define a default value for a variable you should set it in role/defaults/main. yml . Ansible will use that value only if the variable is not defined somewhere else. Using the Jina2 filters is it possible to do something like {{ variable | default(other_variable) }} ?
the map is actually a Jinja2 filter and more information can be found per the Jinja2 official documentation: map() Applies a filter on a sequence of objects or looks up an attribute. This is useful when dealing with lists of objects but you are really only interested in a certain value of it.
You can use the Ansible-specific filters documented here to manipulate your data, or use any of the standard filters shipped with Jinja2 - see the list of built-in filters in the official Jinja2 template documentation. You can also use Python methods to transform data.
In this article, we are going to see the various use cases of Ansible Map Function or Filter. As Ansible Official documentation claims, All Jinja2 Filters can be used within Ansible. It helps us to filter and iterate complex datasets and a list of objects.
The Jinaj2 filters are a very powerful feature and could help us in various tasks for the manipulation with the data. You are welcome to find more filters in the ansible documentation.
use just “+” operator to combine two lists into one, like: "{{ ansible_interfaces + ["VETH-1", "VETH-2"] }}" check here for more advanced example: Advanced list operations in Ansible; Ansible filters and lists operators. Ansible provides a rich set of filters, which you can apply to your variables. Recently, I needed to filter and map a ...
map filter it your friend here.
Something like this:
with_items: "{{ ec2.results | map(attribute='instances') | map('first') | map(attribute='private_ip') | list }}"
The code above is not tested.
You may want to try with debug
first and gradually add map
s to get required result.
Don't forget to put | list
at the end to make your map readable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With