在 Ansible 中正确指定嵌套变量

Specifying a nested variable correctly in Ansible

提问人:Danby 提问时间:8/16/2023 更新时间:8/16/2023 访问量:42

问:

我需要从 ansible 中的嵌套字典中提取一些值,但我似乎做不到。 要么我定义得不好,要么指定得不好。ansible 错误消息当然无济于事。

我加载了一个 vars 文件,其数据结构如下: 对于每个站点,我指定了 vCenter 和域控制器

datacenters:
  - datacenter: Site1
    vars:
      vcenter_instance: vcenter1
      ADC: DC1
  - datacenter: Site2
    vars:
      vcenter_instance: vcenter2
      ADC: DC2
  - datacenter: Site3
    vars:
      vcenter_instance: vcenter1
      ADC: DC3
  - datacenter: TEST
    vars:
      vcenter_instance: vcentertest
      ADC: DC1

我添加了一个调试任务来查看数据在 Ansible 中的样子。我给我这个:


        
        {
            "datacenter": "TEST",
            "vars": {
                "ADC": "DC1",
                "vcenter_instance": "vcentertest"
            }
        }

我在其他位置设置了数据中心值,然后尝试从数组中提取所需的数据

    - name: auto populate some variables based on which datacenter is selected
      set_fact:
        vcenter_hostname: "{{ datacenters[datacenter].vcenter_instance }}"
        ADController: "{{ datacenters[datacenter].ADC }}"
        Library: "'{{ datacenter  + '-' + 'Repository' }}"

我收到错误"The task includes an option with an undefined variable. The error was: 'list object' has no attribute 'TEST'. 'list object' has no attribute 'TEST'\n\nThe error appears to be in '/runner/project/create_vm.yml': line 32, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: auto populate some variables based on which datacenter is selected\

数组 变量 , 散列 ansible

评论


答:

1赞 Vladimir Botka 8/16/2023 #1

将列表转换为字典

  datacenters_dict: "{{ datacenters|
                        items2dict(key_name='datacenter',
                                   value_name='vars') }}"

  datacenters_dict:
    Site1: {ADC: DC1, vcenter_instance: vcenter1}
    Site2: {ADC: DC2, vcenter_instance: vcenter2}
    Site3: {ADC: DC3, vcenter_instance: vcenter1}
    TEST: {ADC: DC1, vcenter_instance: vcentertest}

然后,使用字典并声明变量

  vcenter_hostname: "{{ datacenters_dict[datacenter].vcenter_instance }}"
  ADController: "{{ datacenters_dict[datacenter].ADC }}"
  Library: "{{ datacenter }}-Repository"

例如

    - debug:
        msg: |
          datacenter: {{ datacenter }}
          vcenter_hostname: {{ vcenter_hostname }}
          ADController: {{ ADController }}
          Library: {{ Library }}
      vars:
        datacenter: Site3

  msg: |-
    datacenter: Site3
    vcenter_hostname: vcenter1
    ADController: DC3
    Library: Site3-Repository

用于测试的完整 playbook 示例

- hosts: all

  vars:

    datacenters:
      - datacenter: Site1
        vars: {ADC: DC1, vcenter_instance: vcenter1}
      - datacenter: Site2
        vars: {ADC: DC2, vcenter_instance: vcenter2}
      - datacenter: Site3
        vars: {ADC: DC3, vcenter_instance: vcenter1}
      - datacenter: TEST
        vars: {ADC: DC1, vcenter_instance: vcentertest}

    datacenters_dict: "{{ datacenters|
                          items2dict(key_name='datacenter',
                                     value_name='vars') }}"
    vcenter_hostname: "{{ datacenters_dict[datacenter].vcenter_instance }}"
    ADController: "{{ datacenters_dict[datacenter].ADC }}"
    Library: "{{ datacenter }}-Repository"

  tasks:

    - debug:
        var: datacenters_dict|to_yaml

    - debug:
        msg: |
          datacenter: {{ datacenter }}
          vcenter_hostname: {{ vcenter_hostname }}
          ADController: {{ ADController }}
          Library: {{ Library }}
      vars:
        datacenter: Site3