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

Ansible set_fact循环首次迭代未模板化变量报错排查修复

问题根因

故障与var_list的初始定义无关,完全由my_list的构建逻辑错误导致:

  • 原代码在set_fact的赋值逻辑外层已经使用{{ }}包裹Jinja2表达式,内层拼接的字符串中又嵌套了第二层{{ item }}模板标记。Ansible的Jinja2渲染器不会对表达式内部的字符串字面量做递归渲染,导致最后一轮循环追加的列表元素保留了未渲染的{{ item }}原始文本。
  • 循环任务执行完成后,临时循环变量item会被销毁,后续任务读取my_list时尝试渲染残留的{{ item }}标记,找不到对应变量就会触发报错,最终导致debug输出异常、synchronize任务执行失败。
修复方案

有两种常用修复方式,推荐优先使用无循环的过滤器写法,执行效率更高:

方式1:修正字符串拼接逻辑(保留原有循环结构)

Jinja2中不要嵌套{{ }}标记,使用~作为字符串连接符直接引用item变量即可,修改循环追加的配置行:

- name: Add variables to list
  set_fact:
    my_list: "{{ my_list + ['--exclude ' ~ item ~ '.yaml'] }}"
  loop: "{{ var_list }}"

方式2:使用过滤器一次性生成列表(推荐)

去掉初始化空列表、循环追加两个任务,直接通过map过滤器批量生成目标列表,避免循环拼接的渲染问题:

- name: Build rsync exclude options
  set_fact:
    my_list: "{{ var_list | map('regex_replace', '^(.*)$', '--exclude \\1.yaml') | list }}"
修复后完整Playbook示例
- name: Quick Test Script
  hosts: servers
  vars:
    var_list:
      - AAA
      - BBB
      - CCC
      - DDD
  tasks:
    - name: Build rsync exclude options
      set_fact:
        my_list: "{{ var_list | map('regex_replace', '^(.*)$', '--exclude \\1.yaml') | list }}"

    - name: List of rsync_opts
      debug:
        var: my_list

    - name: Deploy files
      synchronize:
        src: ~/ansible
        dest: "{{ ansible_env.HOME }}/test"
        archive: false
        checksum: true
        owner: false
        group: false
        recursive: true
        links: true
        times: true
        delete: true
        rsync_opts: "{{ my_list }}"

执行后会得到预期的列表值:['--exclude AAA.yaml', '--exclude BBB.yaml', '--exclude CCC.yaml', '--exclude DDD.yaml'],synchronize模块可正常读取参数执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 15:18:23