Ansible:具有相同 yaml 结构的多个 vars_file 不会合并

Mea*_*ell 3 ansible ansible-2.x

我有一个 Ansible playbook,它使用两个 var 文件;一个用于一般属性,其他用于我的特定属性。但是,两个文件中的一些属性共享相同的根 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
Run Code Online (Sandbox Code Playgroud)

aws_management_vars.yml

aws:
  ec2:
    node:
      name: "Management Node"
      instance_type: "t2.micro"
      ...
Run Code Online (Sandbox Code Playgroud)

aws_general_vars.yml

aws:
  region: us-west-1
  ec2:
    env: mih-env
    vpc_id: vpc-abc12345
    ...
Run Code Online (Sandbox Code Playgroud)

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

"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'node'
Run Code Online (Sandbox Code Playgroud)

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

"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'region'
Run Code Online (Sandbox Code Playgroud)

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

安塞布尔 v2.7.8

Vla*_*tka 6

问: “这是否是我可以使用什么来解析具有相同结构的 yml 文件和合并属性的限制?”vars_files?

答:是的。这是 的限制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
Run Code Online (Sandbox Code Playgroud)

  my_vars.aws:
    ec2:
      env: mih-env
      node:
        instance_type: t2.micro
        name: Management Node
      vpc_id: vpc-abc12345
    region: us-west-1
Run Code Online (Sandbox Code Playgroud)

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

答:是的。include_vars是一项任务。将其放在任务的顶部。请参阅变量优先级include_vars(优先级 18.)将覆盖任务、块和角色的变量 (17,16,15)。当把它放在任务的顶部时,include_vars和之间几乎没有区别vars_files(优先级 14)。因此,如果有的话,请使用include_role而不是角色