Write tasks that use advanced looping techniques that illustrate some important use cases for complex loops.
Outcomes
Use filters and lookup plug-ins to iterate over complex data structures.
As the student user on the workstation machine, use the lab command to prepare your system for this exercise.
This command prepares an Ansible project in the /home/student/data-loops/ directory on the workstation machine.
[student@workstation ~]$ lab start data-loops
Procedure 7.3. Instructions
Use a loop with the dict2items filter to transform the rgroups variable into a list.
Review the structure of the rgroups variable section defined in the ~/data-loops/group_vars/all/my_vars.yml file.
### Group variables ### rgroups:accounts:
name: accounts
gid: 7001 development: name: development gid: 7002 ...output omitted...
Review the ~/data-loops/add-groups.yml playbook.
This playbook adds a group to the targeted host.
- name: First task
hosts: servera.lab.example.com
gather_facts: false
become: true
tasks:
- name: Add groups
ansible.builtin.group:
name: accounts
gid: 7001
state: presentModify the playbook to use the loop keyword with the dict2items filter for your loop.
The add-groups.yml playbook should consist of the following content:
---
- name: First task
hosts: servera.lab.example.com
gather_facts: false
become: true
tasks:
- name: Add groups
ansible.builtin.group:
name: "{{ item['key'] }}"
gid: "{{ item['value']['gid'] }}"
state: present
loop: "{{ rgroups | dict2items }}"Run the add-groups.yml playbook to add the groups.
[student@workstation ~]$cd ~/data-loops/[student@workstation data-loops]$ansible-navigator run -m stdout add-groups.ymlPLAY [First task] ******************************************************* TASK [Add groups] ******************************************************* changed: [servera...] => (item={'key': 'accounts'....) changed: [servera...] => (item={'key': 'development'....) ...output omitted... PLAY RECAP *************************************************************** servera...: ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Use a nested loop with the subelements filter to transform the my_users and my_groups variables into a list.
Review the structure of the my_users variable section defined in the ~/data-loops/group_vars/all/my_vars.yml file.
### User variables ### my_users:john:
name: john my_groups:
- accounts - development jane: name: jane my_groups: - manufacturing - marketing ...output omitted...
Review the ~/data-loops/add-users.yml playbook.
This playbook adds a user and puts it in the correct group.
- name: Second task
hosts: servera.lab.example.com
gather_facts: false
become: true
tasks:
- name: Add users and put them in the right groups
ansible.builtin.user:
name: john
append: true
groups: accounts
state: presentModify the playbook to use the loop keyword with the subelements filter for your loop.
The add-users.yml playbook should consist of the following content:
---
- name: Second task
hosts: servera.lab.example.com
gather_facts: false
become: true
tasks:
- name: Add users and put them in the right groups
ansible.builtin.user:
name: "{{ item[0]['name'] }}"
append: true
groups: "{{ item[1] }}"
state: present
loop: "{{ my_users | subelements('my_groups') }}"Run the add-users.yml playbook to add the users.
[student@workstation data-loops]$ ansible-navigator run -m stdout add-users.yml
PLAY [Second task] *******************************************************
TASK [Add users and put them in the right groups] ************************
changed: [servera...] => (item=[{'name': 'john', 'my_groups': ['accounts', ...)
ok: [servera...] => (item=[{'name': 'john', 'my_groups': ['accounts', ...)
...output omitted...
PLAY RECAP ***************************************************************
servera...: ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0Use a loop over the public_keys_lists variable defined in the group_vars/all/my_vars.yml file.
Use the map filter, followed by the flatten filter, to generate a simple list of SSH public key files for all developers.
Update the task's key keyword to contain the file content of each iteration item.
Review the structure of the public_keys_lists variable section defined in the ~/data-loops/group_vars/all/my_vars.yml file.
### Public key variables ### public_key_lists:- username: john
public_keys:
- pubkeys/john/id_rsa.pub - pubkeys/john/laptop_rsa.pub - username: jane public_keys: - pubkeys/jane/id_rsa.pub ...output omitted...
The | |
Each entry in the list is a dictionary with the | |
The |
Review the ~/data-loops/add-keys.yml playbook.
This playbook sets up authorized keys for the developer user.
- name: Third task
hosts: servera.lab.example.com
gather_facts: false
become: true
tasks:
- name: Set up authorized keys
ansible.posix.authorized_key:
user: developer
state: present
key: pubkeys/john/id_rsa.pubModify the playbook to perform the following tasks:
Add a map filter to the end of the expression to extract the public_keys attribute.
It creates a list of lists; each entry in the list is a list of SSH public key files for a particular user.
Add a flatten filter after the map filter to create a single list of files.
Use the file lookup plug-in to configure the key keyword with the file content of each iteration item.
The add-keys.yml playbook should consist of the following content:
- name: Third task
hosts: servera.lab.example.com
gather_facts: false
become: true
tasks:
- name: Set up authorized keys
ansible.posix.authorized_key:
user: developer
state: present
key: "{{ lookup('ansible.builtin.file', item) }}"
loop: "{{ public_key_lists | map(attribute='public_keys') | flatten }}"Install the ansible.posix collection so that it is available to the execution environment.
This collection is needed for the ansible.posix.authorized_key module.
On the workstation machine, open a browser and navigate to hub.lab.example.com.
Log in as the student user using redhat123 as the password.
Navigate to → and then click .
Copy and paste the token in the token variable at the end of the ~/data-loops/ansible.cfg file.
Install the collection:
[student@workstation data-loops]$ansible-galaxy collection \>install -r collections/requirements.yml -p collections/...output omitted...
Run the add-keys.yml playbook to add the keys.
[student@workstation data-loops]$ ansible-navigator run -m stdout add-keys.yml
PLAY [Third task] ********************************************************
TASK [Set up authorized keys] ********************************************
changed: [servera.lab.example.com] => (item=pubkeys/john/id_rsa.pub)
changed: [servera.lab.example.com] => (item=pubkeys/john/laptop_rsa.pub)
changed: [servera.lab.example.com] => (item=pubkeys/jane/id_rsa.pub)
...output omitted...
PLAY RECAP ***************************************************************
servera...: ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0