Ansible 如何根据某些属性选择主机并使用它们的 IP 地址在运行时创建列表

yzf*_*tnt 3 jinja2 ansible ansible-facts ansible-inventory ansible-filter

我有一个关于 ansible 中数据操作的具体问题。

在我的清单文件中,我有一个名为 postgresql 的组,如下所示:

[postgresql]
host1 ansible_host=1.1.1.1 postgresql_cluster_port=5432 postgresql_harole=master
host2 ansible_host=2.2.2.2 postgresql_cluster_port=5432 postgresql_harole=slave postgresql_master_ip=1.1.1.1
host3 ansible_host=3.3.3.3 postgresql_cluster_port=5432 postgresql_harole=slave postgresql_master_ip=1.1.1.1
host4 ansible_host=4.4.4.4 postgresql_cluster_port=5432 postgresql_harole=slave postgresql_master_ip=1.1.1.1
Run Code Online (Sandbox Code Playgroud)

在我的剧本中的某个地方,我需要操作和使用过滤器来创建 postgresql_harole=slave 的所有主机的 IP 地址列表,如下所示:

- hosts: postgresql
  gather_facts: True
  remote_user: root
  tasks:
    - set_facts:
        slave_ip_list: "{{ expressions }}"
Run Code Online (Sandbox Code Playgroud)

我正在拉扯我的头发以获得正确的表达...非常感谢任何帮助!!!!

Vla*_*tka 5

问:“所有主机的IP地址列表postgresql_harole=slave

A:从hostvars中选择属性,例如

    - set_fact:
        slave_ip_list: "{{ hostvars|dict2items|
                           selectattr('value.postgresql_harole', 'eq', 'slave')|
                           map(attribute='value.ansible_host')|
                           list }}"
      run_once: true
Run Code Online (Sandbox Code Playgroud)

给出

  slave_ip_list:
  - 2.2.2.2
  - 3.3.3.3
  - 4.4.4.4
Run Code Online (Sandbox Code Playgroud)

如果存在其他主机主机变量例如,由于. 下面的任务给出了相同的结果- hosts: all

    - set_fact:
        slave_ip_list: "{{ groups.postgresql|
                           map('extract', hostvars)|
                           selectattr('postgresql_harole', 'eq', 'slave')|
                           map(attribute='ansible_host')|
                           list }}"
      run_once: true
Run Code Online (Sandbox Code Playgroud)

更新

您可以简化代码和库存。将声明放入group_vars中。例如,

shell> cat group_vars/postgresql
postgresql_cluster_port: 5432
postgresql_master_ip: "{{ groups.postgresql|
                          map('extract', hostvars)|
                          selectattr('postgresql_harole', 'eq', 'master')|
                          map(attribute='ansible_host')|first }}"
postgresql_slave_ip: "{{ groups.postgresql|
                         map('extract', hostvars)|
                         selectattr('postgresql_harole', 'eq', 'slave')|
                         map(attribute='ansible_host')|list }}"
Run Code Online (Sandbox Code Playgroud)

然后,您可以从清单中删除postgresql_master_ippostgresql_cluster_port

shell> cat hosts
[postgresql]
host1 ansible_host=1.1.1.1 postgresql_harole=master
host2 ansible_host=2.2.2.2 postgresql_harole=slave
host3 ansible_host=3.3.3.3 postgresql_harole=slave
host4 ansible_host=4.4.4.4 postgresql_harole=slave
Run Code Online (Sandbox Code Playgroud)

剧本

- hosts: postgresql
  gather_facts: false
  tasks:
    - debug:
        msg: |
          ansible_host: {{ ansible_host }}
          postgresql_harole: {{ postgresql_harole }}
          postgresql_master_ip: {{ postgresql_master_ip }}
          postgresql_cluster_port: {{ postgresql_cluster_port }}
          postgresql_slave_ip: {{ postgresql_slave_ip }}
Run Code Online (Sandbox Code Playgroud)

给出

shell> ansible-playbook pb.yml 

PLAY [postgresql] ****************************************************************************

TASK [debug] *********************************************************************************
ok: [host1] => 
  msg: |-
    ansible_host: 1.1.1.1
    postgresql_harole: master
    postgresql_master_ip: 1.1.1.1
    postgresql_cluster_port: 5432
    postgresql_slave_ip: ['2.2.2.2', '3.3.3.3', '4.4.4.4']
ok: [host2] => 
  msg: |-
    ansible_host: 2.2.2.2
    postgresql_harole: slave
    postgresql_master_ip: 1.1.1.1
    postgresql_cluster_port: 5432
    postgresql_slave_ip: ['2.2.2.2', '3.3.3.3', '4.4.4.4']
ok: [host4] => 
  msg: |-
    ansible_host: 4.4.4.4
    postgresql_harole: slave
    postgresql_master_ip: 1.1.1.1
    postgresql_cluster_port: 5432
    postgresql_slave_ip: ['2.2.2.2', '3.3.3.3', '4.4.4.4']
ok: [host3] => 
  msg: |-
    ansible_host: 3.3.3.3
    postgresql_harole: slave
    postgresql_master_ip: 1.1.1.1
    postgresql_cluster_port: 5432
    postgresql_slave_ip: ['2.2.2.2', '3.3.3.3', '4.4.4.4']

PLAY RECAP ***********************************************************************************
host1: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host2: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host3: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host4: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Run Code Online (Sandbox Code Playgroud)