如何将多个YAML文件中的id值追加到Ansible列表变量?
从多个YAML文件中收集
id值到列表变量 我有多个包含id键的YAML文件,需要把这些文件里的id值汇总到一个列表变量中。示例YAML文件内容如下:
--- name: somename group: somegroup id: someid
我尝试过两种方法但都没成功:
第一种是用ansible.builtin.command读取文件后处理:
- name: Store job definition content local_action: module: ansible.builtin.command cmd: "cat {{ item.path }}" loop: "{{ definition_files.files }}" register: job_definitions - name: Get a list of existing jobs ids ansible.builtin.set_fact: existing_jobs: "{{ existing_jobs + (item.stdout | to_yaml | map(attribute='id'))}}" loop: "{{ job_definitions.results }}"
第二种是用lookup直接读取文件:
- name: Define empty list ansible.builtin.set_fact: uuid_list: [] - name: Create a list of job ids from template files ansible.builtin.set_fact: uuid_list: "{{uuid_list + lookup('file', item.path | to_yaml).id }}" loop: "{{ definition_files.files }}"
正确的实现方法
方法一:一次性生成列表(推荐)
如果知道YAML文件的路径模式,可以用fileglob匹配所有文件,通过链式操作直接生成目标列表:
- name: 收集所有YAML文件的id到列表 ansible.builtin.set_fact: job_ids: "{{ lookup('fileglob', '**/*.yml', wantlist=True) | map('file') | map('from_yaml') | map(attribute='id') | list }}"
说明:
fileglob:匹配指定路径下的所有YAML文件(**/*.yml表示递归所有子目录,可根据实际路径调整)map('file'):读取每个匹配到的文件内容map('from_yaml'):把文件的字符串内容解析为Ansible字典map(attribute='id'):从每个字典中提取id字段list:把最终的结果转换为列表
方法二:基于已有的文件列表(比如用find模块获取的definition_files.files)
如果已经通过find模块拿到了文件列表,可以逐个处理并追加到列表:
- name: 初始化空列表 ansible.builtin.set_fact: job_ids: [] - name: 逐个读取文件并收集id ansible.builtin.set_fact: job_ids: "{{ job_ids + [ lookup('file', item.path) | from_yaml | attr('id') ] }}" loop: "{{ definition_files.files }}"
说明:
lookup('file', item.path):读取单个文件的内容from_yaml:将字符串解析为字典attr('id')(或直接.id):提取字典中的id值- 用
[ ... ]把单个id包装成列表,才能和job_ids列表做+追加操作
之前尝试的问题分析
- 第一种方法里误用了
to_yaml——这是把数据转为YAML字符串,而我们需要的是把字符串解析为YAML字典,应该用from_yaml;另外map(attribute='id')适用于列表,这里每个item.stdout解析后是单个字典,直接取.id即可。 - 第二种方法里
item.path | to_yaml是多余的,item.path本身就是字符串路径,不需要转YAML;同时lookup返回的是字符串,必须先通过from_yaml解析为字典才能取.id,而且追加时要把单个id包装成列表,否则会报错类型不匹配。
内容的提问来源于stack exchange,提问作者Arno
相关产品推荐
相关产品推荐

