Home > Blockchain >  Ansible playbook loop only calling final loop
Ansible playbook loop only calling final loop

Time:04-02

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 }}{{ "d" | 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

CodePudding user response:

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_fact that 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 }}{{ "d" | 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 }}"

CodePudding user response:

Thank you Zeitounator! So when should I use set_fact? Should I be using vars more often instead?

The below was changed based on your advice, and tested, two files generated, I'll need to work on the hostname entries matching the filename but I'll figure that out, this was a huge step forward after the hours invested, thank you!

- 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 the Filename and Generate Switch Configurations
      vars:
        dest_dir: /home/usr/complete_config/{{ project_name }}
        switch_device_name: '{{ device_name|lower }}-{{ site_abbrev|lower }}-{{ item.installation_floor }}{{ "d" | 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 }}"
  • Related