Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loop over a nested dictionary in Ansible

I've got the following list of dictionaries inside my variables file:

apache_vhosts:
  - servername: "example.com"
    serveralias: "www.example.com"
    username: example
    crons:
      - minute: "*/15 * * * *"
        command: "curl example.com"

  - servername: "foobarr.com"
    serveralias: "www.foobar.com"
    username: foobar
    crons:
      - minute: "*/15 * * * *"
        command: "curl example.com"
          

I want to loop over the crons so I can set them via the Ansible built-in cron module.

For example:

- name: Setup the required crons
  cron:
    name: Set a cron to cURL site
    minute: "{{ item.minute }}"
    job: "{{ item.command }}"
  loop: "{{ apache_vhosts['crons]' }}"

Debugging this I know I'm not getting out the right data. Any pointers for what the correct loop should be here?

like image 554
jsjw Avatar asked Feb 15 '26 05:02

jsjw


1 Answers

You can loop on a list inside a list of dictionaries with the help of the subelements filter.

In this usage, you will have a list in the usual item of a loop, where:

  • item.0 will be the dictionary in the first level of the list
  • item.1 will be the subelement, so, in your case, the elements in the sub-list crons

Given the playbook:

- hosts: localhost
  gather_facts: no

  tasks:
    - debug:
        msg: >- 
          cron: 
            name: "On server {{ item.0.servername }} with username {{ item.0.username }}"
            minute: "{{ item.1.minute }}"
            command: "{{ item.1.command }}"
      loop: "{{ apache_vhosts | subelements('crons') }}"
      loop_control:
        label: "{{ item.0.servername }}"
      vars:
        apache_vhosts:
          - servername: "example.com"
            serveralias: "www.example.com"
            username: example
            crons:
              - minute: "*/15 * * * *"
                command: "curl example.com"
              - minute: "*/30 * * * *"
                command: "curl 30.example.com"

          - servername: "foobarr.com"
            serveralias: "www.foobar.com"
            username: foobar
            crons:
              - minute: "*/15 * * * *"
                command: "curl example.com"

This gives, in the recap:

ok: [localhost] => (item=example.com) => 
  msg: |-
    cron:
      name: "On server example.com with username example"
      minute: "*/15 * * * *"
      command: "curl example.com"
ok: [localhost] => (item=example.com) => 
  msg: |-
    cron:
      name: "On server example.com with username example"
      minute: "*/30 * * * *"
      command: "curl 30.example.com"
ok: [localhost] => (item=foobarr.com) => 
  msg: |-
    cron:
      name: "On server foobarr.com with username foobar"
      minute: "*/15 * * * *"
      command: "curl example.com"
like image 90
β.εηοιτ.βε Avatar answered Feb 17 '26 00:02

β.εηοιτ.βε