使用 ansible 创建树状结构

使用 ansible 创建树状结构

我必须创建一个包含用户和组的 LDAP 结构。
这些组有点复杂,有很多嵌套组等。我需要在我的清单中创建一个树状结构,如下所示:

----
user_groups:
  - name: AllUsers
    members:
      - name: GitlabUsers
        members:
          - name: GitlabAdmins
          - name: GitlabUsers
          - name: GitlabViewers
      - name: StorageUsers
        members:
          - name: StorageAdmins
          - name: StorageReporters
      - name: IPAMUsers
        members:
          - name: IPAMAdmins
          - name: IPAMUsers
            members:
              - name: IPAMUsersStorage
              - name: IPAMUsersLinux
          - name: TowerViewers
      - name: BillingUsers
        members:
          - name: BillingAdmins
          - name: BillingUsers
            members:
              - name: BillingUsersDBA
              - name: BillingUsersReports

在任何编程语言中都可以用递归函数来实现,但 Ansible 不是编程语言

因此,我想知道是否可以在 ansible 中创建这样的结构,无论是使用复杂的 json 查询还是使用 include_tasks 的递归调用,或者类似的东西。

答案1


我猜你正在寻找的是combine一项recursive=True任务set_fact

例如,这个 playboook 收集了hostname => ip我的每个节点的关系,这有助于我确保 /etc/hosts 或 dns 配置在我的集群中一致。

- hosts: all
  tasks:
    - name: Gather hosts ips
      shell: "dig {{ item }} +short"
      register: hosts_ips
      loop: "{{ ansible_play_batch }}"

    - name: dbg
      ansible.builtin.debug:
        var: hosts_ips

    - name: Storing ips as fact
      set_fact:
        hosts_status:
          "{{ hosts_status|default([]) | combine({
              item.item : {
                'ip': item.stdout,
              }
            }, recursive=True)
          }}"
      loop: "{{ hosts_ips.results | default([]) }}"

    - name: dbg hosts_status
      ansible.builtin.debug:
        var: hosts_status

每个服务器上的结果(它们是相同的,所以我觉得很好):

ok: [amsh-1] => {
    "hosts_status": {
        "amsh-1": {
            "ip": "192.168.121.28"
        },
        "amsh-2": {
            "ip": "192.168.121.109"
        },
        "amsh-3": {
            "ip": "192.168.121.229"
        },
        "amsh-4": {
            "ip": "192.168.121.92"
        }
    }
}
ok: [amsh-2] => {
    "hosts_status": {
        "amsh-1": {
            "ip": "192.168.121.28"
        },
        "amsh-2": {
            "ip": "192.168.121.109"
        },
        "amsh-3": {
            "ip": "192.168.121.229"
        },
        "amsh-4": {
            "ip": "192.168.121.92"
        }
    }
}
ok: [amsh-3] => {
    "hosts_status": {
        "amsh-1": {
            "ip": "192.168.121.28"
        },
        "amsh-2": {
            "ip": "192.168.121.109"
        },
        "amsh-3": {
            "ip": "192.168.121.229"
        },
        "amsh-4": {
            "ip": "192.168.121.92"
        }
    }
}
ok: [amsh-4] => {
    "hosts_status": {
        "amsh-1": {
            "ip": "192.168.121.28"
        },
        "amsh-2": {
            "ip": "192.168.121.109"
        },
        "amsh-3": {
            "ip": "192.168.121.229"
        },
        "amsh-4": {
            "ip": "192.168.121.92"
        }
    }
}

我想您将能够用它来创建您的数据结构。

PS:顺便说一句,如果你查找文档,会发现 Ansible 剧本中的内联脚本是用 jinja2 编写的:https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#combining-and-selecting-data

相关内容