Crooks_
Crooks_

Reputation: 99

Looping over list data in Ansible playbooks

In my quest to automate some of our network environment I would like to know how you could loop over different items in nested lists. To make it more clear I will explain what I want to do using my existing inventory and playbook.

Inventory looks as followed, (Dummy Content)

parameters:
- mode: ""
  speed: ""
  duplex: ""
interfaces:
  - Int_One
  - Int_Two

So as you can see I have a list containing some network information (parameters) and another list containing two interfaces. The action that I want to accomplish in my playbook is to configure those two interfaces with the information found in the "parameters" list. In other words, loop over the "interfaces" using the information in the "parameters" list. But as of right now I can't get it to use the right data in the right time

Good to know is that I'm using a predefined "Cisco network module" in my playbook.

Playbook looks as followed,

- name: Deploy Network Interfaces
  "Some network module":
    mode: '{{ item.0.mode }}'
    speed: '{{ item.0.speed }}'
    duplex: '{{ item.0.duplex }}'
    interface: '{{ item.1.interfaces }}'
    state: present
  delegate_to: localhost
  loop: 
    - "{{ parameters }}"
    - "{{ parameters|subelements('interfaces') }}"

As you can see the network module requires the "interface" to be provided. So again I want to iterate over the "interfaces" list and deploy them with the defined data in the "parameters" list.

Anyone that can tell me how to handle this issue?

Thanks in advance!

Upvotes: 2

Views: 62940

Answers (2)

larsks
larsks

Reputation: 312680

Your question is a little confusing. You have two variables; a list named parameters:

parameters:
- mode: ""
  speed: ""
  duplex: ""

And a list named interfaces:

interfaces:
  - Int_One
  - Int_Two

parameters has a single item, while interfaces has two. The fact that they have different numbers of items makes it hard to figure out how they are related. If each interface has unique parameters, you probably want something like this instead:

interfaces:
  - name: Int_One
    mode: ""
    speed: ""
    duplex: ""
  - name: Int_Two
    mode: ""
    speed: ""
    duplex: ""

In which case you would write your playbook like this:

- name: Deploy Network Interfaces
  "Some network module":
    mode: '{{ item.mode }}'
    speed: '{{ item.speed }}'
    duplex: '{{ item.duplex }}'
    interface: '{{ item.name }}'
    state: present
  delegate_to: localhost
  loop: "{{ interfaces }}"

On the other hand, if all interfaces will have the same parameters, then maybe you would structure your data like this:

parameters:
  mode: ""
  speed: ""
  duplex: ""

interfaces:
  - Int_One
  - Int_Two

And write your playbook like this:

- name: Deploy Network Interfaces
  "Some network module":
    mode: '{{ parameters.mode }}'
    speed: '{{ parameters.speed }}'
    duplex: '{{ parameters.duplex }}'
    interface: '{{ item.name }}'
    state: present
  delegate_to: localhost
  loop: "{{ interfaces }}"

Upvotes: 3

JGK
JGK

Reputation: 4178

Given your example, a solution would be the following:

- hosts:
    - localhost
  gather_facts: False

  vars:
    parameters:
    - mode: "auto"
      speed: "1000"
      duplex: "full"
    interfaces:
      - Int_One
      - Int_Two

  tasks:
  - name: DBEUG
    debug:
      msg: >
        mode: {{parameters.0.mode}},
        speed: {{parameters.0.speed}},
        duplex: {{parameters.0.duplex}},
        interface: {{item}}
    loop:
      "{{interfaces}}"

Upvotes: 1

Related Questions