我尝试根据给定的类型动态构建一个数组(fe_components,我将其初始化为空),这些数组实际上来自配置文件。
每种给定类型的数组也来自配置文件。
为了简化考试,我一次完成了所有变量的编写。
我遍历类型并建立相应数组的名称,我想将其内容绑定在一起。
- hosts : all
vars:
# types and fe_components_XX come in real life from different config files
types:
- rs
- gg
fe_components_gg:
- gg_frontend'
fe_components_rs:
- rs_frontend_1
- rs_frontend_2
- storybook
# init empty array to dynamically fill in
fe_components: []
tasks:
# This is what I want to get (written in a static statement)
- debug: msg="{{ fe_components_rs + fe_components_gg }}"
# My dynamic approach fails:
# try to dynamically build up the array for given types
- set_fact:
my_dyn_var: >-
{% for item in types -%}
{% set varname = 'fe_components_' ~ item -%}
{{ fe_components + varname }}
{% endfor -%}
- name: test it
debug:
msg: " {{ my_dyn_var }}"
当我运行它时,我的串联最终出现在“只能串联列表(而不是\” unicode \”)以列出” 消息中
fatal: [frank-lap]: FAILED! => {"msg": "Unexpected templating type error occurred on ({% for item in types -%}\n {% set varname = 'fe_components_' ~ item -%}\n {{ fe_components + varname }}\n{% endfor -%}): can only concatenate list (not \"unicode\") to list"}
我做错了什么?
答案 0 :(得分:0)
以下满足您的要求。重点:
default
filter 我们在这里:
---
- name: My test play
hosts : localhost
gather_facts: false
vars:
types:
- rs
- gg
- notexists
fe_components_gg:
- gg_frontend
fe_components_rs:
- rs_frontend_1
- rs_frontend_2
- storybook
tasks:
- name: Static demo of what we are looking for
debug:
msg: "{{ fe_components_rs + fe_components_gg }}"
- name: Build my list dynamically from typed list
vars:
list_name: "fe_components_{{ item }}"
set_fact:
my_dyn_var : "{{ my_dyn_var | default([]) + lookup('vars', list_name, default=[]) }}"
loop: "{{ types }}"
loop_control:
label: "{{ list_name }}"
- name: Show my dynamic var
debug:
var: my_dyn_var
结果:
PLAY [My test play] *****************************************************************************************************************************************************************************************************************************************************
TASK [Static demo of what we are looking for] ***************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": [
"rs_frontend_1",
"rs_frontend_2",
"storybook",
"gg_frontend"
]
}
TASK [Build my list dynamically from typed list] ************************************************************************************************************************************************************************************************************************
ok: [localhost] => (item=fe_components_rs)
ok: [localhost] => (item=fe_components_gg)
ok: [localhost] => (item=fe_components_notexist)
TASK [Show my dynamic var] **********************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"my_dyn_var": [
"rs_frontend_1",
"rs_frontend_2",
"storybook",
"gg_frontend"
]
}
PLAY RECAP **************************************************************************************************************************************************************************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
答案 1 :(得分:0)
我刚刚升级到V2.9.0的ansible版本确实存在问题,现在的输出就像Zeitounator的。
我知道我的情况也有效:
- name: Build my list dynamically from typed list
vars:
list_name: "fe_components_{{ item }}"
set_fact:
my_dyn_var : "{{ my_dyn_var | default([]) + lookup('vars', list_name) }}"
loop: "{{ types }}"
loop_control:
label: "{{ list_name }}"
when: vars[list_name] is defined
TASK [Build my list dynamically from typed list] ***********************************************************************************************************************************************
ok: [localhost] => (item=fe_components_rs)
ok: [localhost] => (item=fe_components_gg)
skipping: [localhost] => (item=fe_components_notexists)
答案 2 :(得分:0)
在我的第一个示例中,我首先结合了上面的解决方案(带有查找变量)的数组。 在继续我的项目时,我也需要组合类型字典的子元素。
- name: My test play
hosts : localhost
gather_facts: false
vars:
types:
- rs
- gg
- notexists
# backend
be_components: {}
solr_cores: {}
backend_config_rs:
be_components :
rs-document: { dbaccess: True, version: latest, mvn_id: rs-document }
rs-attachments:{ dbaccess: True, version: latest, mvn_id: rs-attachments }
cores:
rs: { name: rs_core, dir: /var/solr/data/jurisdict }
backend_config_gg:
be_components :
gg-document: { dbaccess: True, version: latest, mvn_id: gg-document }
gg-importer: { dbaccess: True, version: latest, mvn_id: gg-importer }
cores:
rs: { name: gg_core, dir: /var/solr/data/law }
tasks:
# Static demo of what I currently do
- name: "dyn-config | combine backend variables with RS backend config"
set_fact:
be_components: "{{ be_components | combine ( backend_config_rs.be_components ) }}"
solr_cores: "{{ solr_cores | combine ( backend_config_rs.cores ) }}"
when: "backend_config_rs is defined"
- name: "dyn-config | combine backend variables with GG backend config"
set_fact:
be_components: "{{ be_components | combine ( backend_config_gg.be_components ) }}"
solr_cores: "{{ solr_cores | combine ( backend_config_gg.cores ) }}"
when: "backend_config_gg is defined"
- debug: var=be_components
- debug: var=solr_cores
但是后来我尝试以一种动态的方式进行操作,我发现查找vars访问不会返回字典的子元素。
- name: "try with lookup"
vars:
listname: "backend_config_{{ item }}"
set_fact:
be_components: "{{ be_components | combine (lookup('vars', listname.components)) }}"
loop: "{{ types }}"
loop_control:
label: "{{ listname }}"
when: vars[listname] is defined
我知道了
FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'components'\n
是否可以通过查找变量访问字典的子元素?