如何在 ansible 剧本中有条件地向字典添加 key/value
How to add a key/value to a dict in an ansible playbook, conditional
假设我想在变量 test_var
存在时添加 InterestingVar
字典键和关联值(通过 -e in command line
传递),我该怎么做?
# 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
我唯一能想到的就是将字典与 Ansible 2.0 中引入的 set_fact
task when your condition is met. This relies on the 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
在以下文件中定义您的变量:
vagrant@Test-01:~$ cat tags.yml
tags:
Name: xxx
Env: "{{ env }}"
vagrant@Test-01:~$ cat optional_tags.yml
tags:
InterestingVar: "{{ test_var }}"
这将为您提供所需的输出,但您必须确保在未定义 test_var
时不包含 optional_vars.yml
:
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
请注意,在使用此方法时,任何预期通过继承覆盖的字典现在都将合并字典,因此这对于覆盖其清单中内容的任何人来说可能不是那么有用。
假设我想在变量 test_var
存在时添加 InterestingVar
字典键和关联值(通过 -e in command line
传递),我该怎么做?
# 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
我唯一能想到的就是将字典与 Ansible 2.0 中引入的 set_fact
task when your condition is met. This relies on the 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
在以下文件中定义您的变量:
vagrant@Test-01:~$ cat tags.yml
tags:
Name: xxx
Env: "{{ env }}"
vagrant@Test-01:~$ cat optional_tags.yml
tags:
InterestingVar: "{{ test_var }}"
这将为您提供所需的输出,但您必须确保在未定义 test_var
时不包含 optional_vars.yml
:
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
请注意,在使用此方法时,任何预期通过继承覆盖的字典现在都将合并字典,因此这对于覆盖其清单中内容的任何人来说可能不是那么有用。