如何在有条件的ansible playbook中为dict添加键/值

时间:2015-10-28 14:51:44

标签: jinja2 ansible ansible-playbook

假设我想在变量InterestingVar存在时添加test_var dict键和相关值(与-e in command line一起传递),我该怎么办?< / p>

# ansible-playbook ./add_to_dict_on_condition.yml -i 127.0.0.1, -e env=test -e test_var=123
- hosts: localhost
  gather_facts: no
  vars:
    - tags:
        InterestingVar: "{{test_var}}" # How to omit this line if test_var == '' ?
        Name: xxx
        Env: "{{ env }}"

  tasks:
    - debug: var=tags

我测试了

 InterestingVar: "{{test_var|default(omit)}}

但我明白了:

"InterestingVar": "__omit_place_holder__caca01e207397883640613b08e8ce3a8fbdd6"

而不是什么。

非常感谢任何帮助。

我使用ansible 1.8

1 个答案:

答案 0 :(得分:8)

我唯一能想到的就是在满足条件时将字典与set_fact任务结合起来。这取决于Ansible 2.0中引入的combine filter

- hosts: localhost
  connection: local
  gather_facts: no
  vars:
    - tags:
        Name: xxx
        Env: "{{ env }}"
    - optional_tags:
        InterestingVar: "{{ test_var }}"

  tasks:
    - name: combine tags
      set_fact:
        tags: "{{ tags | combine(optional_tags) }}"
      when: test_var is defined

    - name: debug tags
      debug: var=tags

输出以下内容然后未定义test_var:

vagrant@Test-02:~$ ansible-playbook -i "localhost," conditional_key.yml -e "env=test"

PLAY ***************************************************************************

TASK [combine tags] ************************************************************
skipping: [localhost]

TASK [debug tags] **************************************************************
ok: [localhost] => {
    "changed": false,
    "tags": {
        "Env": "test",
        "Name": "xxx"
    }
}

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0

定义时的输出:

vagrant@Test-02:~$ ansible-playbook -i "localhost," conditional_key.yml -e "env=test" -e "test_var=123"

PLAY ***************************************************************************

TASK [combine tags] ************************************************************
ok: [localhost]

TASK [debug tags] **************************************************************
ok: [localhost] => {
    "changed": false,
    "tags": {
        "Env": "test",
        "InterestingVar": "123",
        "Name": "xxx"
    }
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0

如果您无法使用2.0+,则另一个选项可能是更改Ansible's hash behaviour以合并字典而不是通过设置覆盖它们:

hash_behaviour=merge

ansible.cfg

有了这个,你可以使用这样的东西:

- hosts: localhost
  connection: local
  gather_facts: no
  vars:
    - tags:
        Name: xxx
        Env: "{{ env }}"
    - tags:
        InterestingVar: "{{ test_var }}"

  tasks:
    - name: debug tags
      debug: var=tags

使用以下文件中定义的vars:

vagrant@Test-01:~$ cat tags.yml
tags:
  Name: xxx
  Env: "{{ env }}"
vagrant@Test-01:~$ cat optional_tags.yml
tags:
  InterestingVar: "{{ test_var }}"

然后,这会为您提供所需的输出,但是当您没有定义optional_vars.yml时,您必须确保不要包含test_var

vagrant@Test-01:~$ ansible-playbook -i "localhost," conditional_key.yml -e "env=test" -e "test_var=123" -e@tags.yml -e@optional_tags.yml

PLAY [localhost] **************************************************************

TASK: [debug tags] ************************************************************
ok: [localhost] => {
    "var": {
        "tags": {
            "Env": "test",
            "InterestingVar": "123",
            "Name": "xxx"
        }
    }
}

PLAY RECAP ********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0

请注意,使用此方法时,通过继承任何预期的字典覆盖现在将合并字典,因此对于任何覆盖其清单中的内容的人来说,这可能不是那么有用。