在 Ansible 中循环嵌套字典

Loop over a nested dictionary in Ansible

我的变量文件中有以下字典列表:

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"
          

我想遍历 crons 以便我可以通过 Ansible 内置 cron 模块来设置它们。

例如:

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

调试这个我知道我没有得到正确的数据。关于正确循环应该在此处的任何指示?

您可以在 subelements filter.

的帮助下在字典列表中的列表上循环

在这种用法中,您将在通常的 item 循环中得到一个列表,其中:

  • item.0 将是列表第一层的字典
  • item.1 将是子元素,因此,在您的情况下,子列表中的元素 crons

鉴于剧本:

- 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"

总结一下:

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"