问题描述
我有一个试点项目,在group_vars
中保留了许多公共变量。
group_vars/
group1.yml
group2.yml
group3.yml
对于不同的实现(通常是每个客户端),我想维护保留文件,该文件将覆盖group_vars
的内容,该文件的内容可以具有以下格式,即client1.yml
: / p>
group1:
var11_to_override: "foo"
var12_to_override: "bar"
group2:
var21_to_override: "foo"
var22_to_override: "bar"
是否可以简单地对Ansible说文件client1.yml
覆盖group_vars
的内容?
include_vars
模块肯定是与set_facts
一起循环的第一步,但是它可能需要复杂的jinja2过滤器表达式...
我是否要编写新模块或更新hostvars
的过滤器?
解决方法
最终由自定义过滤器解决,由另一个过滤器更新字典:
filter_plugins/vars_update.py
import copy
import collections
class FilterModule(object):
def update_hostvars(self,_origin,overlay):
origin = copy.deepcopy(_origin)
for k,v in overlay.items():
if isinstance(v,collections.Mapping):
origin[k] = self.update_hostvars(origin.get(k,{}),v)
else:
origin[k] = v
return origin
def filters(self):
return {"update_hostvars": self.update_hostvars}
..并在更新所有变量时使用此过滤器:
- name: Include client file
include_vars:
file: "{{ client_file_path }}"
name: client_overlay
- name: Update group_vars by template client
set_fact:
"{{ item.key }}": "{{ hostvars[inventory_hostname][item.key] | update_hostvars(item.value) }}"
with_dict: "{{ client_overlay }}"
,
使用此线程中给出的示例,我制定了自己的解决方案:
-
“外部来源”使用--extra-vars“@”在库存项目中馈送。文件内容本身作为 base64 编码内容上传,然后解码/写入 fs。
-
外部文件具有每个角色/组的覆盖列表,如下所示:
role_overrides: [{ "groups": [ "my-group" ],"overrides": { "foo": "value","bar": "value",} },
但随后显然 jsonified...
-
过滤模块
#!/usr/bin/env python
类过滤器模块(对象): def过滤器(自我): 返回 { “filter_hostvars_overrides”:self.filter_hostvars_overrides, }
def filter_hostvars_overrides(self,role_overrides,group_names):
"""
filter the overrides for the ones to apply for this host
[
{
"groups": [
"my-group"
],"overrides": {
"foo: 42,}
},:param group_names: List of groups this host is member of
:param role_overrides: document with all overrides; to be filtered using groups_names
:return: items to be set
"""
overrides = {}
for idx,per_group_overrides in enumerate(role_overrides):
groups = per_group_overrides.get("groups",[])
if set(groups).intersection(set(group_names)):
overrides.update(per_group_overrides.get("overrides",{}))
return overrides
-
播放代码:
- name: Apply group overrides set_fact: "{{ item.key }}": "{{ item.value }}" with_dict: "{{ role_overrides | filter_hostvars_overrides(group_names) }}"