Ansible set_fact 来自基于项目类型的字典
Ansible set_fact from dictionary based on item type
我正在从 Kubernetes 配置映射(下面的 cm_config
)中读取字典,并使用它来替换 defaults/main.yml
中设置的变量,如下所示:
- name: 'Overwrite defaults'
set_fact: "{{ item.key }}={{ item.value }}"
with_dict: "{{ cm_config }}"
只要项目是简单变量,这就可以正常工作。但是一旦 item
是另一本字典,我想合并这些值。
如何将其整合到上述任务中?我考虑了两次 运行 循环,并进行了某种类型检查。不确定这将如何工作。另外,我相信可能有更好的方法?
下面的一个解决方案可以在单个任务中实现您的要求,只需一点 jinja2 模板和 vars
lookup 即可获取现有的 dict
内容。关键是根据变量类型计算值。
请注意,这没有考虑 var 是 list
的情况,它将被替换为所有其他类型的值。这不会处理现有变量和配置映射之间的类型不匹配。例如如果您现有的 var 是 string
并且配置映射中的相应 var 是 dict
它将中断。
以下剧本:
---
- hosts: localhost
gather_facts: false
vars:
cm_config:
label1: toto
label2:
a_value: 1
other_value: 2
label3:
a_value: 3
other_value: 4
label4: tata
label1: I am set in play
label3:
some_value: I'm a poor lonesome cowboy
tasks:
- name: show initial state
debug:
var: "{{ item.key }}"
with_dict: "{{ cm_config }}"
- name: Process values from config map
vars:
my_value: >-
{% if item.value is mapping %}
{{ lookup('vars', item.key, default={}) | combine(item.value) }}
{% else %}
{{ item.value }}
{% endif %}
set_fact:
"{{ item.key }}": "{{ my_value }}"
with_dict: "{{ cm_config }}"
- name: Show the result after processing config map
debug:
var: "{{ item.key }}"
with_dict: "{{ cm_config }}"
给出以下结果:
PLAY [localhost] ****************************************************************************************************************************************************************************************************************************
TASK [show initial state] *******************************************************************************************************************************************************************************************************************
ok: [localhost] => (item=label1) => {
"ansible_loop_var": "item",
"item": {
"key": "label1",
"value": "toto"
},
"label1": "I am set in play"
}
ok: [localhost] => (item=label2) => {
"ansible_loop_var": "item",
"item": {
"key": "label2",
"value": {
"a_value": 1,
"other_value": 2
}
},
"label2": "VARIABLE IS NOT DEFINED!"
}
ok: [localhost] => (item=label3) => {
"ansible_loop_var": "item",
"item": {
"key": "label3",
"value": {
"a_value": 3,
"other_value": 4
}
},
"label3": {
"some_value": "I'm a poor lonesome cowboy"
}
}
ok: [localhost] => (item=label4) => {
"ansible_loop_var": "item",
"item": {
"key": "label4",
"value": "tata"
},
"label4": "VARIABLE IS NOT DEFINED!"
}
TASK [Process values from config map] *******************************************************************************************************************************************************************************************************
ok: [localhost] => (item={'key': 'label1', 'value': 'toto'})
ok: [localhost] => (item={'key': 'label2', 'value': {'a_value': 1, 'other_value': 2}})
ok: [localhost] => (item={'key': 'label3', 'value': {'a_value': 3, 'other_value': 4}})
ok: [localhost] => (item={'key': 'label4', 'value': 'tata'})
TASK [Show the result after processing config map] ******************************************************************************************************************************************************************************************
ok: [localhost] => (item=label1) => {
"ansible_loop_var": "item",
"item": {
"key": "label1",
"value": "toto"
},
"label1": " toto "
}
ok: [localhost] => (item=label2) => {
"ansible_loop_var": "item",
"item": {
"key": "label2",
"value": {
"a_value": 1,
"other_value": 2
}
},
"label2": " {'a_value': 1, 'other_value': 2} "
}
ok: [localhost] => (item=label3) => {
"ansible_loop_var": "item",
"item": {
"key": "label3",
"value": {
"a_value": 3,
"other_value": 4
}
},
"label3": " {'some_value': \"I'm a poor lonesome cowboy\", 'a_value': 3, 'other_value': 4} "
}
ok: [localhost] => (item=label4) => {
"ansible_loop_var": "item",
"item": {
"key": "label4",
"value": "tata"
},
"label4": " tata "
}
PLAY RECAP **********************************************************************************************************************************************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
我正在从 Kubernetes 配置映射(下面的 cm_config
)中读取字典,并使用它来替换 defaults/main.yml
中设置的变量,如下所示:
- name: 'Overwrite defaults'
set_fact: "{{ item.key }}={{ item.value }}"
with_dict: "{{ cm_config }}"
只要项目是简单变量,这就可以正常工作。但是一旦 item
是另一本字典,我想合并这些值。
如何将其整合到上述任务中?我考虑了两次 运行 循环,并进行了某种类型检查。不确定这将如何工作。另外,我相信可能有更好的方法?
下面的一个解决方案可以在单个任务中实现您的要求,只需一点 jinja2 模板和 vars
lookup 即可获取现有的 dict
内容。关键是根据变量类型计算值。
请注意,这没有考虑 var 是 list
的情况,它将被替换为所有其他类型的值。这不会处理现有变量和配置映射之间的类型不匹配。例如如果您现有的 var 是 string
并且配置映射中的相应 var 是 dict
它将中断。
以下剧本:
---
- hosts: localhost
gather_facts: false
vars:
cm_config:
label1: toto
label2:
a_value: 1
other_value: 2
label3:
a_value: 3
other_value: 4
label4: tata
label1: I am set in play
label3:
some_value: I'm a poor lonesome cowboy
tasks:
- name: show initial state
debug:
var: "{{ item.key }}"
with_dict: "{{ cm_config }}"
- name: Process values from config map
vars:
my_value: >-
{% if item.value is mapping %}
{{ lookup('vars', item.key, default={}) | combine(item.value) }}
{% else %}
{{ item.value }}
{% endif %}
set_fact:
"{{ item.key }}": "{{ my_value }}"
with_dict: "{{ cm_config }}"
- name: Show the result after processing config map
debug:
var: "{{ item.key }}"
with_dict: "{{ cm_config }}"
给出以下结果:
PLAY [localhost] ****************************************************************************************************************************************************************************************************************************
TASK [show initial state] *******************************************************************************************************************************************************************************************************************
ok: [localhost] => (item=label1) => {
"ansible_loop_var": "item",
"item": {
"key": "label1",
"value": "toto"
},
"label1": "I am set in play"
}
ok: [localhost] => (item=label2) => {
"ansible_loop_var": "item",
"item": {
"key": "label2",
"value": {
"a_value": 1,
"other_value": 2
}
},
"label2": "VARIABLE IS NOT DEFINED!"
}
ok: [localhost] => (item=label3) => {
"ansible_loop_var": "item",
"item": {
"key": "label3",
"value": {
"a_value": 3,
"other_value": 4
}
},
"label3": {
"some_value": "I'm a poor lonesome cowboy"
}
}
ok: [localhost] => (item=label4) => {
"ansible_loop_var": "item",
"item": {
"key": "label4",
"value": "tata"
},
"label4": "VARIABLE IS NOT DEFINED!"
}
TASK [Process values from config map] *******************************************************************************************************************************************************************************************************
ok: [localhost] => (item={'key': 'label1', 'value': 'toto'})
ok: [localhost] => (item={'key': 'label2', 'value': {'a_value': 1, 'other_value': 2}})
ok: [localhost] => (item={'key': 'label3', 'value': {'a_value': 3, 'other_value': 4}})
ok: [localhost] => (item={'key': 'label4', 'value': 'tata'})
TASK [Show the result after processing config map] ******************************************************************************************************************************************************************************************
ok: [localhost] => (item=label1) => {
"ansible_loop_var": "item",
"item": {
"key": "label1",
"value": "toto"
},
"label1": " toto "
}
ok: [localhost] => (item=label2) => {
"ansible_loop_var": "item",
"item": {
"key": "label2",
"value": {
"a_value": 1,
"other_value": 2
}
},
"label2": " {'a_value': 1, 'other_value': 2} "
}
ok: [localhost] => (item=label3) => {
"ansible_loop_var": "item",
"item": {
"key": "label3",
"value": {
"a_value": 3,
"other_value": 4
}
},
"label3": " {'some_value': \"I'm a poor lonesome cowboy\", 'a_value': 3, 'other_value': 4} "
}
ok: [localhost] => (item=label4) => {
"ansible_loop_var": "item",
"item": {
"key": "label4",
"value": "tata"
},
"label4": " tata "
}
PLAY RECAP **********************************************************************************************************************************************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0