'Ansible playbook loop only calling final loop
I'm trying to create a playbook that will loop based on the number of devices, creating a different file for each, and subsequently each then getting a hostname within that matches that of the filename.
It looks like the loop caches the 2 filenames, but doesn't create, and then later has forgotten the frist in the loop, remembers its attributes but uses the intended filename of the second in the loop.
Been at this a while, am I missing something obvious?
playbooks/test.yaml
- name: Create Folder Structure
hosts: switches
gather_facts: false
vars:
project_name: test
switch_stacks:
- id: 01
installation_floor: 1
- id: 02
installation_floor: 2
device_name: swi
site_abbrev: lon
tasks:
- name: Create Site Specific Folder
file:
path: /home/usr/complete_config/{{ project_name }}
state: directory
mode: 0755
- name: Set Destination Directory & Filename for Switch Configurations
set_fact:
dest_dir: /home/usr/complete_config/{{ project_name }}
switch_device_name: '{{ device_name|lower }}-{{ site_abbrev|lower }}-{{ item.installation_floor }}{{ "%02d" | format(item.id) }}'
loop: "{{ switch_stacks }}"
- name: Create Switch Configurations
hosts: switches
gather_facts: false
tasks:
- name: Generate Switch Configurations
template:
src: /home/usr/templates/switch-template.j2
dest: "{{ dest_dir }}/{{ switch_device_name }}"
lstrip_blocks: yes
delegate_to: localhost
See the folder structure before:
usr@ans:~$ tree complete_config/test
complete_config/test [error opening dir]
0 directories, 0 files
Running of the playbook:
usr@ans:~$ ansible-playbook playbooks/test.yaml
PLAY [Create Folder Structure] **************************************************************************************
TASK [Create Site Specific Folder] **********************************************************************************
changed: [switch]
TASK [Set Destination Directory & Filename for Switch Configurations] ***********************************************
ok: [switch] => (item={'id': 1, 'installation_floor': 1})
ok: [switch] => (item={'id': 2, 'installation_floor': 2})
PLAY [Create Switch Configurations] *********************************************************************************
TASK [Generate Switch Configurations] *******************************************************************************
changed: [switch -> localhost]
PLAY RECAP **********************************************************************************************************
switch : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
The folder structure afterwards:
usr@ans:~$ tree complete_config/test/
complete_config/test/
└── swi-lon-202
0 directories, 1 file
Solution 1:[1]
You're using set_fact wrongly. Since you override the variables you set on every iteration only the last one remains. What you want to do is:
- get rid of your
set_factthat is useless here - get rid of the second play and move the task at the end of the first changing it like so (written on spot and untested)
- name: Generate Switch Configurations
vars:
dest_dir: /home/usr/complete_config/{{ project_name }}
switch_device_name: '{{ device_name|lower }}-{{ site_abbrev|lower }}-{{ item.installation_floor }}{{ "%02d" | format(item.id) }}'
template:
src: /home/usr/templates/switch-template.j2
dest: "{{ dest_dir }}/{{ switch_device_name }}"
lstrip_blocks: yes
delegate_to: localhost
loop: "{{ switch_stacks }}"
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Zeitounator |
