我需要一些帮助来匹配 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