Ansible:具有相同Yaml结构的多个vars_files不会合并

时间:2020-08-05 10:26:21

标签: ansible ansible-2.x

我有一本使用两个var文件的Ansible剧本;一个用于一般属性,其他用于我特定属性。但是,两个文件中都有一些属性共享相同的根YAML根结构(aws.ec2),但是当我运行剧本时,似乎这些属性不会合并到一棵树中,但是最后列出的文件会覆盖前一个文件对于使用aws.ec2的任何道具。

剧本

- name: Play 1. Create AWS Environment
  hosts: localhost

  vars_files:
    - var_files/aws_management_vars.yml
    - var_files/aws_general_vars.yml

aws_management_vars.yml

aws:
  ec2:
    node:
      name: "Management Node"
      instance_type: "t2.micro"
      ...

aws_general_vars.yml

aws:
  region: us-west-1
  ec2:
    env: mih-env
    vpc_id: vpc-abc12345
    ...

运行剧本时,如果我按此顺序有vars文件,它会抱怨找不到aws.ec2.node

"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'node'

如果我调换订单,它会抱怨找不到aws.region

"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'region'

这是vars_files的限制吗?还有什么我可以使用的东西,它们可以解析yml文件并合并具有相同结构的属性?我知道我可以重命名文件中的结构,但是如果可能的话,我希望它保持这种方式。

Ansible v2.7.8

1 个答案:

答案 0 :(得分:0)

Q:“这是vars_files的限制吗?我可以使用哪些方法来解析yml文件并合并具有相同结构的属性?”

A:是的。这是vars_files的限制。 控制变量的合并方式是可能的。参见DEFAULT_HASH_BEHAVIOUR。但这不推荐。引用:“ 通常,除非您认为您绝对需要此设置,否则我们建议您不要使用此设置。”

有一个简单的解决方案。使用include_vars,将包含的数据放入字典,然后combine。设置recursive=True以合并键。例如

    - include_vars:
        file: var_files/aws_management_vars.yml
        name: management
    - include_vars:
        file: var_files/aws_general_vars.yml
        name: general
    - set_fact:
        my_vars: "{{ management|combine(general, recursive=True) }}"
    - debug:
        var: my_vars.aws

给予

  my_vars.aws:
    ec2:
      env: mih-env
      node:
        instance_type: t2.micro
        name: Management Node
      vpc_id: vpc-abc12345
    region: us-west-1

Q:“ include_vars抱怨无法在剧本级别使用它。我需要将其添加到剧本中正在运行的所有任务的顶部吗?

A:是的。 include_vars是一项任务。将其放在任务的顶部。参见Variable precedenceinclude_vars(优先级18)将覆盖任务,块和角色的变量(17,16,15)。将其放在任务的顶部时,include_varsvars_files之间几乎没有区别(优先级14)。因此,请使用include_role代替roles(如果有)。