根据字典中的列表创建var

Create var based on list in dict

想象一下 4 台不同主机上的这条命令。

# on host 1
my_dict:
  ip: 10.0.0.111
  roles:
    - name: something
      observer: false

# on host 2
my_dict:
  ip: 10.0.0.112
  roles:
    - name: something
      observer: false

# on host 3
my_dict:
  ip: 10.0.0.113
  roles:
    - name: something
      observer: true

# on host 4
my_dict:
  ip: 10.0.0.114
  roles:
    - name: whatever

当 Ansible 为所有 4 台主机运行时,我希望它为每个具有角色名称 'something' 的主机构建一个变量。期望的输出是:

10.0.0.111 10.0.0.112 10.0.0.113:observer

有2个要求:

我最终想在 Jinja 模板中使用 var,所以对我来说,var 可以通过 Ansible 任务设置或作为 jinja 模板设置。

这行不通:

- name: set fact for ip
  debug:
    msg: >-
      {{ ansible_play_hosts |
      map('extract', hostvars, ['my_dict', 'ip'] ) |
      join(' ') }}
  when: ???

您可以创建两个列表:

  • 一个带有基于 observer 属性
  • 条件的 IP 后缀
  • 另一个有IP

然后将它们拉回一起。

鉴于:

- debug:
    msg: >-
      {{ 
        _ips | zip(_is_observer) | map('join') | join(' ')
      }}
  vars:
    _hosts: >-
      {{ 
        hostvars 
        | dict2items 
        | selectattr('key', 'in', ansible_play_hosts)
        | selectattr('value.my_dict.roles.0.name', '==', 'something')
      }}
    _is_observer: >-
      {{ 
        _hosts
        | map(attribute='value.my_dict.roles.0.observer') 
        | map('replace', false, '') 
        | map('replace', true, ':observer')
      }}
    _ips: >-
      {{
        _hosts
        | map(attribute='value.my_dict.ip')
      }}

这产生:

TASK [debug] *************************************************************
ok: [localhost] => 
  msg: 10.0.0.111 10.0.0.112 10.0.0.113:observer