如何覆盖ansibles数组变量的子集?

时间:2015-03-23 16:51:22

标签: arrays yaml ansible ansible-playbook

如何在Ansible中仅覆盖数组的一部分? 也就是说,我的角色中有一组默认值(./roles/delta/default/main.yml),如下所示:

---
delta:
  name: "delta-snapshot"
  roles: []

然后我有一个非常简单的./vars/delta.yml,内容如下:

---
delta:
  roles:
    - name: admin
      rights: "0x3FF"
    - name: test
      rights: "0x20F"
    - name: "simple"
      rights: "0x005"

这里的问题是我必须提供delta.name变量,因为delta完全被新版本替换,这不是我想要的。我已经尝试定义了像delta.roles: ...delta[roles]: ...这样的列表,但后来它被视为一个完全不同的变量名,而是使用了空列表。

1 个答案:

答案 0 :(得分:2)

我的经验是,避免在ansible中使用相同的变量名两次,因为变量的处理方式。这隐含意味着避免覆盖/更改变量值(而是创建具有不同名称的新变量)。作者明确拒绝回答任何与范围/优先级等相关的问题。

那就是说,对于你的情况,最简单的解决方案是创建一个新变量,如:

---
delta:
  name: "{{delta.name}}"
  roles:
    - name: admin
      rights: "0x3FF"
    # ...

或者如果由于范围而导致递归问题,则更改名称: - )

---
overridden_delta:
  name: "{{delta.name}}"
  roles:
    - name: admin
      rights: "0x3FF"
    # ...

如果你想保留这个名字,那就欺骗它吧:

- hosts: localhost
  vars:
      dict1: {
        'key1': 'value1',
        'key2': 'value2',
      }
  tasks:
  - debug: msg="before = {{dict1}}"
  - set_fact: {
      dict1: {
       key1: "{{dict1.key1}}",
       key2: 'overriden value2'
      }
     }
  - debug: msg="after = {{dict1}}"

或者使用银弹(可读性稍差的IMO)自定义过滤器:How to assign an array to a variable in an Ansible-Playbook