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

Gil*_*not 8 jinja2 ansible ansible-playbook

假设我想InterestingVar在变量test_var存在(传递-e in command line)时添加dict键和相关值,我该怎么做?

# 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
Run Code Online (Sandbox Code Playgroud)

我测试过了

 InterestingVar: "{{test_var|default(omit)}}
Run Code Online (Sandbox Code Playgroud)

但我得到:

"InterestingVar": "__omit_place_holder__caca01e207397883640613b08e8ce3a8fbdd6"
Run Code Online (Sandbox Code Playgroud)

而不是没有.

任何帮助将不胜感激.

我用 ansible 1.8

yda*_*coR 8

我唯一能想到的就是在set_fact满足条件时将字典与任务结合起来.这依赖于Ansible 2.0中引入的combine过滤器.

- 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
Run Code Online (Sandbox Code Playgroud)

哪个输出以下,然后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
Run Code Online (Sandbox Code Playgroud)

定义时输出:

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
Run Code Online (Sandbox Code Playgroud)

如果您无法使用2.0+,则另一个选项可能是更改Ansible的哈希行为以合并词典,而不是通过设置来覆盖它们:

hash_behaviour=merge
Run Code Online (Sandbox Code Playgroud)

在你的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
Run Code Online (Sandbox Code Playgroud)

使用以下文件中定义的变量:

vagrant@Test-01:~$ cat tags.yml
tags:
  Name: xxx
  Env: "{{ env }}"
vagrant@Test-01:~$ cat optional_tags.yml
tags:
  InterestingVar: "{{ test_var }}"
Run Code Online (Sandbox Code Playgroud)

然后,它会为您提供所需的输出,但您必须确保optional_vars.ymltest_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
Run Code Online (Sandbox Code Playgroud)

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