通过外部源覆盖group_vars

问题描述

我有一个试点项目,在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 }}"
,

使用此线程中给出的示例,我制定了自己的解决方案:

  1. “外部来源”使用--extra-vars“@”在库存项目中馈送。文件内容本身作为 base64 编码内容上传,然后解码/写入 fs。

  2. 外部文件具有每个角色/组的覆盖列表,如下所示:

         role_overrides: [{
           "groups": [
               "my-group"
           ],"overrides": {
               "foo": "value","bar": "value",}
       },

但随后显然 jsonified...

  1. 过滤模块

    #!/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
  1. 播放代码:

         - name: Apply group overrides
          set_fact:
            "{{ item.key }}": "{{ item.value }}"
          with_dict: "{{ role_overrides | filter_hostvars_overrides(group_names) }}"
    

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...