目前我有以下库存(简化(:
children:
child-1111:
param: some-data-1111
child-1112:
param: some-data-1112
child-1113:
param: some-data-1113
当然,当你需要一千个主机,而不是只有三个和很多参数的替换时,这是不好的。我想写这样的东西(不起作用(:
children:
"child-{{item}}":
param: "some-data-{{item}}"
loop:
- 1111
- 1112
- 1113
我看到的所有例子总是产生列表,而不是字典
此外,loop
似乎只适用于任务,而不适用于库存。
我该如何做到这一点?
这类需求往往使用add_host
模块进行管理。
给出剧本:
- hosts: localhost
gather_facts: no
tasks:
- add_host:
name: "child-{{ item.name }}"
param: "some-data-{{ item.param }}"
group: dynamic_hosts
loop: "{{ _hosts }}"
vars:
_hosts:
- name: 1111
param: 1111-bis
- name: 1112
param: 1112-bis
- name: 1113
param: 1113-bis
- hosts: dynamic_hosts
gather_facts: no
tasks:
- debug:
msg: "On host `{{ item }}` the value of `param` is `{{ hostvars[item].param }}`"
loop: "{{ ansible_play_hosts }}"
run_once: true
我们正在构建一个名为dynamic_hosts
的动态库存组,然后我们可以在同一个剧本中使用它。
这实际上会产生:
PLAY [localhost] ****************************************************************
TASK [add_host] *****************************************************************
ok: [localhost] => (item={'name': 1111, 'param': '1111-bis'})
ok: [localhost] => (item={'name': 1112, 'param': '1112-bis'})
ok: [localhost] => (item={'name': 1113, 'param': '1113-bis'})
PLAY [dynamic_hosts] ************************************************************
TASK [debug] ********************************************************************
ok: [child-1111] => (item=child-1111) =>
msg: On host `child-1111` the value of `param` is `some-data-1111-bis`
ok: [child-1111] => (item=child-1112) =>
msg: On host `child-1112` the value of `param` is `some-data-1112-bis`
ok: [child-1111] => (item=child-1113) =>
msg: On host `child-1113` the value of `param` is `some-data-1113-bis`
一些前言:
- 你的问题不太准确。我的例子只会给出一个通用的方法,它比您的方法更具可扩展性,但很快就会达到极限
- 您的示例不是有效的yaml清单。此外,还不清楚您是使用名称
children
来声明默认all
的子组,还是要将其用作组名(我强烈建议您不要这样做( - 根据主机负载的静态清单中的主机名,必须声明特定于主机的变量,这通常是一个糟糕设计的迹象,或者你应该切换到完全动态清单,或者通过
add_host
动态管理你的剧本中的主机(请参见@βεηιτβε的答案(
下面的示例声明了名为my_children
的组中的一系列主机,并利用主机命名约定捕获它们的编号,并在为组声明的变量中重用它
inv.yml
---
my_children:
vars:
param: "some-data-{{ inventory_hostname.split('-')[1] }}"
hosts:
child-[1111:1113]:
您可以看到主机被正确解析:
$ ansible-inventory -i inv.yml --list
{
"_meta": {
"hostvars": {
"child-1111": {
"param": "some-data-{{ inventory_hostname.split('-')[1] }}"
},
"child-1112": {
"param": "some-data-{{ inventory_hostname.split('-')[1] }}"
},
"child-1113": {
"param": "some-data-{{ inventory_hostname.split('-')[1] }}"
}
}
},
"all": {
"children": [
"my_children",
"ungrouped"
]
},
"my_children": {
"hosts": [
"child-1111",
"child-1112",
"child-1113"
]
}
}
变量被正确解释:
$ ansible my_children -i inv.yml -m debug -a "msg={{ param }}"
child-1111 | SUCCESS => {
"msg": "some-data-1111"
}
child-1112 | SUCCESS => {
"msg": "some-data-1112"
}
child-1113 | SUCCESS => {
"msg": "some-data-1113"
}
Q:">需要一千个主机(例如"child-1111"参数:"some-data1111"(">
A: 使用范围和构建的插件。例如
shell> cat inventory/01-hosts
child-[1111:1113]
shell> cat inventory/02-constructed.yml
plugin: constructed
strict: True
groups:
group_children: inventory_hostname.startswith('child-')
compose:
param: "'some-data-' ~ inventory_hostname|split('-')|last"
测试
shell> ansible-inventory -i inventory --list --yaml
all:
children:
group_children:
hosts:
child-1111:
param: some-data-1111
child-1112:
param: some-data-1112
child-1113:
param: some-data-1113
ungrouped: {}
并在战术手册中使用
- hosts: all
tasks:
- debug:
var: param
给出
ok: [child-1111] =>
param: some-data-1111
ok: [child-1112] =>
param: some-data-1112
ok: [child-1113] =>
param: some-data-1113