有没有规定一个主机不能分成两个组?例如,事实上文档说,
建议您根据主机的目的(角色)定义组
但我的一些角色排除了其他角色。也就是说它们不能重叠。就像生产和开发一样。有没有一种方法可以将这种逻辑融入库存中的组中。确保一台主机没有连接到两个冲突的组?
答案1
为了将生产和开发分开,您需要为它们保留单独的库存文件。
这样,您就可以针对开发、集成和生产运行完全相同的剧本。
“生产”和“开发”不是 ansible 库存上下文中的组,而“网络服务器”和“数据库”则是。
一种常见的情况是:在开发中将所有内容安装在一台主机上,但在生产中拥有专用的数据库服务器。
您的开发清单看起来类似:
[webserver]
host1
[dbserver]
host1
和你的生产环境类似:
[webserver]
host1
[dbserver]
host2
每当您的角色重叠时,您就需要编写一个新角色以包含所需的配置文件。
答案2
问:“是否有一种方法可以将这种逻辑融入到清单中的组中。以确保一台主机不会连接到两个冲突的组?”
A:没有。库存中没有这样的方法。但它可以很容易地在任务中实现。 Ansible 变量group_names
保存主机所属组的列表。让我们定义一个列表exclusive_groups
并测试intersect
exclusive_groups|intersect(group_names)|length > 1
例如,与库存
$ cat hosts
[group1]
test_01 ansible_host=10.1.0.51
test_02 ansible_host=10.1.0.52
[group2]
test_03 ansible_host=10.1.0.53
test_04 ansible_host=10.1.0.54
[group3]
test_02 ansible_host=10.1.0.52
test_03 ansible_host=10.1.0.53
剧本
- hosts: all
vars:
exclusive_groups:
- group1
- group3
tasks:
- set_fact:
member_exclusive_groups: "{{ exclusive_groups|intersect(group_names) }}"
- block:
- debug:
msg: "{{ msg.split('\n') }}"
vars:
msg: |-
{{ inventory_hostname }} is member of exclusive groups
{{ member_exclusive_groups|to_yaml }}
End of host.
- meta: end_host
when: member_exclusive_groups|length > 1
给出
skipping: [test_01]
ok: [test_02] => {
"msg": [
"test_02 is member of exclusive groups",
"[group1, group3]",
"",
"End of host."
]
}
skipping: [test_03]
skipping: [test_04]
答案3
从其他答案中提炼出想法,考虑这个解决方案。如果主机位于多个独占组中,则它会完全终止。
- name: Exclusive group check
assert:
msg: "{{ inventory_hostname }} may only be in only one of these inventory groups: {{ exclusive_groups|intersect(group_names)|join(',') }}"
that:
- exclusive_groups|intersect(group_names)|length <= 1
设置exclusive_groups
为专有组名列表;例如,在库存中:
all:
vars:
exclusive_groups:
- webservers
- databases
将任务放置在剧本中的第一件事,以便它可以尽早执行检查并终止。