将 item.x 值与 inventory_hostname 匹配

将 item.x 值与 inventory_hostname 匹配

我需要一些帮助来匹配 inventory_hostname 和 item.host(来自 vars_file)。最好的方法是什么?我是个新手,搞不清楚。

我的要求是:

  • 我必须从库存文件中调用所有主机。

  • 我必须从 ansible_inventory 匹配 item.host,如果它存在,则在与所有 item.hosts 匹配的主机上运行 shell 命令,然后退出。

  • filelist.yml 是一个每天都在变化的动态文件,所有主机都存在于库存中,但我只想利用文件中的主机。

我有一个 list.yml 文件,其中包含主机名、磁盘和版本信息

$ cat list.yml
---
list:
  - host: host1
    diskn: disk0
    os: 7

  - host: host2
    diskn: disk4
    os: 7

  - host: lhost6
    diskn: hdisk7
    os: 7
---

在剧本中我尝试匹配值但没有成功。

---
- name: My playbook   
  hosts: all   
  vars_file: 
    - list.yml   
  tasks:
   - name: Remove file from client
     shell: "rm -f /tmp/me"
     when:
       - "('item.host' in inventory_hostname) and (ansible_distribution_version == 'item.os')"
     loop: "{{ list }}"
     register: fileopt
   - debug: var=fileopt
----

请提出可以解决此问题的解决方案。

答案1

例如,给定库存

shell> cat hosts
host01
host02
host03

和列表

list:
  - host: host01
    diskn: disk0
    os: 13.0
  - host: host02
    diskn: disk4
    os: 13.0
  - host: host06
    diskn: hdisk7
    os: 13.0

创建允许主机的列表

my_hosts: "{{ list|map(attribute='host')|list }}"

给出

my_hosts:
  - host01
  - host02
  - host06

接下来,创建允许的主机和操作系统版本的词典

my_os: "{{ list|items2dict(key_name='host', value_name='os') }}"

给出

  my_os:
    host01: 13.0
    host02: 13.0
    host06: 13.0

现在,以下任务有条件地删除文件并显示注册的结果

    - name: Remove file from client
      file:
        state: absent
        path: /tmp/me
      when:
        - inventory_hostname in my_hosts
        - ansible_distribution_version ==
          my_os[inventory_hostname]|default('None')|string
      register: fileopt
    - debug:
        var: fileopt

给出

TASK [Remove file from client] *********************************************
skipping: [host03]
ok: [host02]
ok: [host01]

TASK [debug] ***************************************************************
ok: [host01] => 
  fileopt:
    changed: false
    failed: false
    path: /tmp/me
    state: absent
ok: [host02] => 
  fileopt:
    changed: false
    failed: false
    path: /tmp/me
    state: absent
ok: [host03] => 
  fileopt:
    changed: false
    skip_reason: Conditional result was False
    skipped: true

正如预期的那样,host03列表中缺少的内容已被跳过。


或者,如果允许的主机列表与所有主机相比要小得多,则创建动态组可能会更有效。例如,在第一个 play 中创建一个允许的主机组,并在第二个 play 中使用它

- name: Create group my_hosts
  hosts: all
  gather_facts: true
  vars:
    list:
      - host: host01
        diskn: disk0
        os: 13.0
      - host: host02
        diskn: disk4
        os: 13.0
      - host: host06
        diskn: hdisk7
        os: 13.0
    my_hosts: "{{ list|map(attribute='host')|list }}"
    my_os: "{{ list|items2dict(key_name='host', value_name='os') }}"
  tasks:
    - set_fact:
        _my_os: "{{ ansible_distribution_version ==
                    my_os[inventory_hostname]|default('None')|string }}"
    - name: Create group my_hosts
      add_host:
        name: "{{ item }}"
        groups: my_hosts
      loop: "{{ hostvars|dict2items|
                selectattr('key', 'in', my_hosts)|
                selectattr('value._my_os')|
                map(attribute='key')|
                list }}"
      run_once: true

- name: Remove file from my_hosts
  hosts: my_hosts
  gather_facts: false
  tasks:
    - name: Remove file from client
      file:
        state: absent
        path: /tmp/me
      register: fileopt
    - debug:
        var: fileopt

给出

PLAY [Create group my_hosts] ***************************************

TASK [Gathering Facts] *********************************************
ok: [host03]
ok: [host01]
ok: [host02]

TASK [set_fact] ****************************************************
ok: [host03]
ok: [host02]
ok: [host01]

TASK [Create group my_hosts] ***************************************
ok: [host01] => (item=host01)
ok: [host01] => (item=host02)

PLAY [Remove file from my_hosts] ***********************************

TASK [Remove file from client] *************************************
ok: [host01]
ok: [host02]

TASK [debug] *******************************************************
ok: [host01] => 
  fileopt:
    changed: false
    failed: false
    path: /tmp/me
    state: absent
ok: [host02] => 
  fileopt:
    changed: false
    failed: false
    path: /tmp/me
    state: absent

相关内容