【问题标题】:Looping through ansible dictionary to assign dictionary values循环遍历 ansible 字典以分配字典值
【发布时间】:2023-11-17 12:55:01
【问题描述】:

有没有办法循环遍历 ansible 字典来分配其他 ansible 字典值?

我的 group_vars/all 中有以下内容:

domain_controllers:
  dc0:
    hostname: "dc0"
    ip_address: "192.168.1.0"
  dc1:
    hostname: "dc1"
    ip_address: "192.168.1.1"
  dc2:
    hostanme: "dc2"
    ip_address: "192.168.1.2"

我有一个通用的 keepalived 角色,它配置了服务器角色用来为这些域控制器创建 VIP 的 keepalived。

以下是我的roles/servers/forward/vars.yml,keepalived 角色使用它来构建keepalived.conf 文件。

virtual_server:
  - virutal_server_ip: "192.168.1.10"
    virtual_server_port: 389
    ...
    real_servers:
      - real_ip: "192.168.1.0"
        real_port: 389
        description: "dc0"
        ...
      - real_ip: "192.168.1.1"
        real_port: 389
        description: "dc1"
        ...
      - real_ip: "192.168.1.2"
        real_port: 389
        description: "dc2"
        ...

  - virtual_server_ip: "192.168.1.10"
    virtual_server_port: 636
    ...
    real_servers:
      - real_ip: "192.168.1.0"
        real_port: 636
        description: "dc0"
        ...
      - real_ip: "192.168.1.1"
        real_port: 636
        description: "dc1"
        ...
      - real_ip: "192.168.1.2"
        real_port: 636
        description: "dc2"
        ...

我已经在 keepalived 角色中设置了 jinja 格式,可以基于这些变量构建 /etc/keepalived.conf

我想做的是根据domain_controllers 字典的内容分配这些变量。我如何使用set_facts 来分配这样的大型嵌套字典?

我只想循环访问domain_controllers,因为我想在升级和/或迁移到新 DC 时更新我的​​group_vars/all,因为我还有其他使用此变量的剧本。

还可以在vars/main.yml 中分配这些变量,而不是通过set_facts 任务?

【问题讨论】:

    标签: dictionary ansible yaml ansible-inventory


    【解决方案1】:

    我用以下方法解决了这个问题:

    在 group_vars/all 中:

    domain_controllers:
      - ip_address: "192.168.1.0"
        hostname: "dc0"
      - ip_address: "192.168.1.1"
        hostname: "dc1"
      - ip_address: "192.168.1.2"
        hostname: "dc2"
    

    在我的 vars 文件中,我使用以下命令调用列表:

    virtual_server:
      - virutal_server_ip: "192.168.1.10"
        virtual_server_port: 389
        ...
        real_servers:
          - real_ip: "{{ domain_controllers.0.ip_address }}"
            real_port: 389
            description: "{{ domain_controllers.0.hostname }}"
            ...
          - real_ip: "{{ domain_controllers.1.ip_address }}"
            real_port: 389
            description: "{{ domain_controllers.1.hostname }}"
            ...
          - real_ip: "{{ domain_controllers.2.ip_address }}"
            real_port: 389
            description: "{{ domain_controllers.2.hostname }}"
            ...
    
      - virtual_server_ip: "192.168.1.10"
        virtual_server_port: 636
        ...
        real_servers:
          - real_ip: "{{ domain_controllers.0.ip_address }}"
            real_port: 636
            description: "{{ domain_controllers.0.hostname }}"
            ...
          - real_ip: "{{ domain_controllers.1.ip_address }}"
            real_port: 636
            description: "{{ domain_controllers.1.hostname }}"
            ...
          - real_ip: "{{ domain_controllers.2.ip_address }}"
            real_port: 636
            description: "{{ domain_controllers.2.hostname }}"
            ...
    

    这样做的缺点是如果domain_controllers 中没有至少 3 个项目,则剧本会出错。我仍然想找到一种方法来循环列表。

    【讨论】: