如何在vars中使用已注册的ansible变量的字典? [英] How to use a dictionary of registered ansible variables in vars?

查看:297
本文介绍了如何在vars中使用已注册的ansible变量的字典?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用vars将多个变量传递给任务.目前,我正在执行以下操作

I want to pass multiple variables to a task using vars. Currently, I am doing it like below

vars:
    var1_name: "var1_value"
    var2_name: "var2_value"

随着变量数量的增加,我宁愿使用vars将变量字典传递给任务.我已经构造了一个像下面这样的变量字典

As the number of variables can grow in size, I'd rather prefer to pass the dictionary of variables to the task using vars. I have constructed a dictionary of variables like below

- name: set fact
  hosts: localhost
  tasks:
  - set_fact:
      variables: "{{ variables|default({}) | combine( {item.variable: item.value} ) }}"
    with_items:
    - variable: var1_name
      value: "var1_value"
    - variable: var2_name
      value: "var2_name"

字典看起来像这样:

"variables": {
    "var1_name": "var1_value",
    "var2_name": "var2_value",
}

现在,我想使此字典中的变量可用于在其他主机上执行的角色.

Now, I want to make variables in this dictionary available to roles executing on other hosts.

但是,当我尝试将字典传递给vars时,如下所示

But, when I tried to pass dictionary to vars like below

vars: "{{ variables }}"

Ansible引发错误:

Ansible throws the error:

ERROR! Vars in a Play must be specified as a dictionary, or a list of dictionaries

如何在vars中传递字典变量?

How to pass a dictionary variable in vars?

推荐答案

在Ansible源代码中进行了一些搜索之后,即使是Ansible face的开发人员,这似乎也是一个问题.在某些集成测试中,由于相同的错误,有一些特定的测试被注释掉了.

After doing some searching through the Ansible source code, it looks like this is an issue even the developers of Ansible face. In some integration tests, there are specific tests that are commented out because of this same error.

ansible/tests/integration/targets/include_import/role/test_include_role.yml

    ## FIXME Currently failing with
    ## ERROR! Vars in a IncludeRole must be specified as a dictionary, or a list of dictionaries
    # - name: Pass all variables in a variable to role
    #   include_role:
    #     name: role1
    #     tasks_from: vartest.yml
    #   vars: "{{ role_vars }}"

我还发现这是被调用以包含变量的基础函数:

I also found out that this is the underlying function that is being called to include the variables:

def _load_vars(self, attr, ds):
        '''
        Vars in a play can be specified either as a dictionary directly, or
        as a list of dictionaries. If the later, this method will turn the
        list into a single dictionary.
        '''

        def _validate_variable_keys(ds):
            for key in ds:
                if not isidentifier(key):
                    raise TypeError("'%s' is not a valid variable name" % key)

        try:
            if isinstance(ds, dict):
                _validate_variable_keys(ds)
                return combine_vars(self.vars, ds)
            elif isinstance(ds, list):
                all_vars = self.vars
                for item in ds:
                    if not isinstance(item, dict):
                        raise ValueError
                    _validate_variable_keys(item)
                    all_vars = combine_vars(all_vars, item)
                return all_vars
            elif ds is None:
                return {}
            else:
                raise ValueError
        except ValueError as e:
            raise AnsibleParserError("Vars in a %s must be specified as a dictionary, or a list of dictionaries" % self.__class__.__name__,
                                     obj=ds, orig_exc=e)
        except TypeError as e:
            raise AnsibleParserError("Invalid variable name in vars specified for %s: %s" % (self.__class__.__name__, e), obj=ds, orig_exc=e)

似乎因为"{{}}"实际上只是一个YAML字符串,所以Ansible无法将其识别为dict,这意味着vars属性不会通过Jinja2引擎传递,而是被评估为确实是.

Seems as if since "{{ }}" is actually just a YAML string, Ansible doesn't recognize it as a dict, meaning that the vars attribute isn't being passed through the Jinja2 engine but instead being evaluated for what it actually is.

传递YAML对象的唯一方法是使用锚,但是这将要求对对象进行整体定义而不是动态定义.

The only way to pass YAML objects around would be to use anchors, however this would require that the object be defined in whole instead of dynamically.

var: &_anchored_var 
  attr1: "test"
  att2: "bar"

vars:
  <<: *_anchored_var

这篇关于如何在vars中使用已注册的ansible变量的字典?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆