You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ansible中使用set_fact创建自定义字典列表?

解决Ansible中set_fact创建字典列表变量的报错问题

问题背景

需要通过set_fact生成一个仅包含path和files字段的字典列表,原始数据previous.results的结构如下:

[
  { "path": "/aaa", "files": ["f1.txt", "f2.txt"], "其他字段": "任意值" },
  { "path": "/bbb", "files": ["f3.txt"], "其他字段": "任意值" }
]

期望生成的目标变量结构:

[
  {"path": "/aaa", "files": ["f1.txt", "f2.txt"]},
  {"path": "/bbb", "files": ["f3.txt"]}
]

尝试的代码及报错

使用以下set_fact任务时触发了变量未定义错误:

- name: init
  ansible.builtin.set_fact:
    files: "{{ files|default([]) + [ { path: item['path'], files: item.keys() } ] }}"
  with_items: "{{ previous.results }}"

报错信息:

fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'path' is undefined. 'path' is undefined

The error appears to be in 'test-playbook.yaml': line 47, column 5, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:


  - name: init
    ^ here
"}

问题原因及解决方案

报错原因

  1. Jinja2表达式中,字典的键如果不加引号会被当作变量解析,代码里的path和files未加引号,Ansible会尝试寻找名为path的变量,导致报错。
  2. item.keys()是错误的取值方式,应该直接提取item['files']字段的内容。

修正后的代码

方案一:循环构建变量

- name: 初始化files变量
  ansible.builtin.set_fact:
    files: "{{ files|default([]) + [ { 'path': item['path'], 'files': item['files'] } ] }}"
  loop: "{{ previous.results }}"

方案二:用过滤器简化(推荐)

无需循环,直接通过json_query过滤器提取指定字段:

- name: 生成目标字典列表
  ansible.builtin.set_fact:
    files: "{{ previous.results | map('json_query', '{path: path, files: files}') | list }}"

后续双循环创建文件示例

得到files变量后,可通过双循环完成目录创建和文件写入:

- name: 创建目标目录
  ansible.builtin.file:
    path: "{{ item.0.path }}"
    state: directory
  loop: "{{ files | subelements('files') }}"

- name: 向文件写入内容
  ansible.builtin.copy:
    content: "自定义文件内容"
    dest: "{{ item.0.path }}/{{ item.1 }}"
  loop: "{{ files | subelements('files') }}"

内容的提问来源于stack exchange,提问作者sctx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 18:05:08