I am relatively new to Ansible and I am struggling to understand how to perform the following scenario: I have an array with AWS security group names looking like this
['Security-Group-Name1', 'SecurityGroup-Name2', 'SecurityGroup-Name3']
However, what I want is to have an array of SecurityGroupIds. Using Ansible I have the ec2_group_info as an option to retrieve information about a security group. So far so good ...
Now comes my question. I need to loop through the above array using ec2_group_info, set the name of the security group I need and return the retrieved Id into a new array so in the end I have something like this.
['Security-Group-Id1', 'SecurityGroup-Id2', 'SecurityGroup-Id3']
I know I need to use a loop with sort of a dynamic index. But it is not really clear to me how to do this in Ansible.
I am aware of the latest loop section of Ansible Docs and I find them more than confusing... https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html
Edit:
This is the current code which works as needed:
- name: Installing pip if not existing on host
pip:
name: boto3
- name: Get SecurityGroupId information
ec2_group_info:
filters:
group_name: ['SG-One', 'SG-Two']
vpc_id: 'vpc-id'
register: my_groups
- set_fact:
my_group_ids: '{{ my_groups.security_groups | map(attribute="group_id") | list }}'
- debug:
msg: "{{ my_groups }}"
- debug:
msg: "{{ my_group_ids }}"
This is the outcome:
TASK [Gathering Facts] ***************************************************
ok: [localhost]
TASK [machine-provisioning : Installing pip if not existing on host] ************
ok: [localhost]
TASK [machine-provisioning : Get SecurityGroupId information] *************************
ok: [localhost]
TASK [machine-provisioning : set_fact] *********************************
ok: [localhost]
TASK [machine-provisioning : debug] ***********************************************
ok: [localhost] => {
"msg": [
"sg-00000000",
"sg-11111111"
]
}
On that linked page about loops, you'll observe the use of register:
, which is how you'd capture the result of that ec2_group_info:
lookup, then use the map
jinja filter to extract map(attribute="group_id")
from the resulting list of results; you have to feed the output of map
into the list
filter, because map
and a few others are python generators, and thus need a terminal action to materialize their data. The set_fact:
is how ansible does "assignment"
- ec2_group_info:
filters:
group_name: '{{ the_group_names }}'
vpc_id: '{{ my_vpc_id }}'
register: my_groups
- set_fact:
my_group_ids: '{{ my_groups.security_groups | map(attribute="group_id") | list }}'
yields:
ok: [localhost] => {"ansible_facts": {"my_group_ids": ["sg-0c5c277ed1edafb54", "sg-7597a123"]}, "changed": false}