我有一个库存,例如:
all:
children:
server_group1:
hosts:
host1:
server_group2:
children:
app1:
hosts:
host2:
host3:
app2:
hosts:
host4:
host5:
server_group3:
...
我已经像这样组织了我的服务器变量:
> cat group_vars/server_group2/app1
app1:
name1: value1
name2: value2
> cat group_vars/server_group2/app2
app2:
name1: value11
name2: value21
我试图以该组的名字命名我的字典(从而使它们独一无二)并在我的剧本中访问它:
hosts: server_group2
tasks:
- name: check file
local_action: stat path=path/to/test/{{hostvars[0].name1}}
register: payld_txt
- name: conditional transfer
copy:
src: path/to/test/{{hostvars[0].name1}}
dest: /svr/path/{{hostvars[0].name2}}
when: payld_txt.stat.exists
我最终遇到了这个错误: 该任务包含一个带有未定义变量的选项。错误是:“name1”未定义
我哪里出错了?
在继续之前,您需要修复不尊重 yaml 源的 ansible 结构的清单。下面一个简单的命令可以给你一些提示:
$ ansible -i inventories/test.yml all --list-hosts
[WARNING]: Skipping unexpected key (server_group1) in group (all), only "vars", "children" and "hosts" are valid
[WARNING]: Skipping unexpected key (server_group2) in group (all), only "vars", "children" and "hosts" are valid
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
hosts (0):
正确的语法是:
---
all:
children:
server_group1:
hosts:
host1:
server_group2:
children:
app1:
hosts:
host2:
host3:
app2:
hosts:
host4:
host5:
现在给出:
$ ansible -i inventories/test.yml all --list-hosts
hosts (5):
host1
host2
host3
host4
host5
``hostvars[0].name1`` The error was: 'name1' is undefined
问:“我哪里出错了?”
A:变量
name1
是字典app1
或app2
的项目。必须引用 app1.name1
或 app2.name1
。除此之外,
hostvars
是字典而不是数组。 hostvars[0]
不存在。字典的项目必须由键引用。比如下面这个剧
- hosts: server_group2
tasks:
- set_fact:
my_keys: "{{ hostvars.keys()|list }}"
run_once: true
- debug:
var: my_keys
run_once: true
- debug:
msg: "{{ hostvars[item].app1.name1 }}"
loop: "{{ my_keys }}"
when: "item in groups['app1']"
run_once: true
- debug:
msg: "{{ hostvars[item].app2.name1 }}"
loop: "{{ my_keys }}"
when: "item in groups['app2']"
run_once: true
给予
ok: [host5] =>
my_keys:
- host5
- host4
- host3
- host2
- host1
ok: [host5] => (item=host3) =>
msg: value1
ok: [host5] => (item=host2) =>
msg: value1
ok: [host5] => (item=host5) =>
msg: value11
ok: [host5] => (item=host4) =>
msg: value11
可以选择使用 json_query 创建键列表
- set_fact:
my_keys: "{{ hostvars|dict2items|json_query('[].key') }}"
run_once: true
剧本的简化版
- hosts: server_group2
tasks:
- debug:
msg: "{{ hostvars[inventory_hostname].app1.name1 }}"
when: "inventory_hostname in groups['app1']"
- debug:
msg: "{{ hostvars[inventory_hostname].app2.name1 }}"
when: "inventory_hostname in groups['app2']"
给予
skipping: [host5]
skipping: [host4]
ok: [host3] =>
msg: value1
ok: [host2] =>
msg: value1
ok: [host5] =>
msg: value11
ok: [host4] =>
msg: value11
skipping: [host3]
skipping: [host2]
事实上,解决
hostvars[inventory_hostname]
是没有必要的。下面的简化任务给出相同的输出。
- debug:
msg: "{{ app1.name1 }}"
when: "inventory_hostname in groups['app1']"
- debug:
msg: "{{ app2.name1 }}"
when: "inventory_hostname in groups['app2']"