Ansible: looping over nested dictionary variables

Viewed 46

I have the following vars.yml file with nested dict.:

hosts:
  server_1:    
    apps:
      - x1
      - x2
      - x3
      - x4
      - x5
    storage:
      -
      -
    cpu:
      -
      -
  server_2:    
    apps:
      - y1
      - y2
      - y3
      - y4
      - y5
    storage:
      -
      -
    cpu:
      -
      -
server_N:    
    apps:
      - n1
      - n2
      - n3
      - n4
      - n5

And I want to use it in the following example playbook as a loop trough the variables so the task is executed multiple times on the dict:

- hosts: localhost
  gather_facts: no
  vars_files:
    - vars.yml

  tasks:
    - name: Install apps
      debug:
          msg: "{{ item.value }}"
          msg: "{{ item.value.apps }}"
      with_dict: "{{ hosts }}"

I want to use them as variables and get as a result loop iteration where server and app are correlated.

1. msg: "server_1"
   msg: "x1"
2. msg: "server_1"
   msg: "x2"
3.  msg: "server_1"
   msg: "x3"
....etc
6. msg: "server_2"
   msg: "y1"
7. msg: "server_2"
   msg: "y2"
....etc

I think you got the idea. Also it shouldn't matter how many "server_N" are available in the vars.yml file!

What is the simplest and correct way to get this result?

2 Answers

The correct way is to put that information into the files host_vars/server1, host_vars/server2, etc.:

# this is host_vars/server1
apps:
  - x1
  - x2
  - x3
  - x4
  - x5
storage:
  -
  -
cpu:
  -
  -

Then, your playbook looks like this:

- hosts: all
  gather_facts: no

  tasks:
  - name: Install apps
    debug:
      msg: "{{ item }}"
    with_items: "{{ apps }}"
    delegate_to: localhost      # if really necessary

The task

    - debug:
        msg: "{{ item.0.key }} {{ item.1 }}"
      with_subelements:
        - "{{ hosts|dict2items }}"
        - value.apps

gives

    "msg": "server_N n1"
    "msg": "server_N n2"
    "msg": "server_N n3"
    "msg": "server_N n4"
    "msg": "server_N n5"
    "msg": "server_1 x1"
    "msg": "server_1 x2"
    "msg": "server_1 x3"
    "msg": "server_1 x4"
    "msg": "server_1 x5"
    "msg": "server_2 y1"
    "msg": "server_2 y2"
    "msg": "server_2 y3"
    "msg": "server_2 y4"
    "msg": "server_2 y5"
Related