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

Ansible使用循环生成变量创建目录树时的问题咨询

问题:Ansible批量生成目录树时变量引用出错

我计划通过定义目录树模式字典,结合指定索引列表让Ansible创建多套相似目录树,编写了如下Playbook:

- hosts: [localhost]
  vars:
    instances: [1,2,3,4]
    dirs:
    - path: "/srvs/hosting{{ instance }}/dir1"
    - path: "/srvs/hosting{{ instance }}/dir2"
#   and so on ......

  tasks:
    - debug:
        msg: "{{ item[1].path }}"
      loop: "{{ instances | product(dirs) | list }}"
      vars:
        instance: "{{ item[0] }}"

执行后出现错误:

fatal: [localhost]: FAILED! => {"msg": "[{'path': '/srvs/hosting{{ instance }}/dir1'}, {'path': '/srvs/hosting{{ instance }}/dir2'}]: {{ item[0] }}: 'item' is undefined"}

我期望的输出是:

ok: [localhost] => (item=[1, {'path': '/srvs/hosting1/dir1'}]) => {
    "msg": {
        "path": "/srvs/hosting1/dir1"
    }
}
ok: [localhost] => (item=[1, {'path': '/srvs/hosting1/dir2'}]) => {
    "msg": {
        "path": "/srvs/hosting1/dir2"
    }
}
ok: [localhost] => (item=[2, {'path': '/srvs/hosting2/dir1'}]) => {
    "msg": {
        "path": "/srvs/hosting2/dir1"
    }
}
ok: [localhost] => (item=[2, {'path': '/srvs/hosting2/dir2'}]) => {
    "msg": {
        "path": "/srvs/hosting2/dir2"
    }
}
ok: [localhost] => (item=[3, {'path': '/srvs/hosting3/dir1'}]) => {
    "msg": {
        "path": "/srvs/hosting3/dir1"
    }
}
ok: [localhost] => (item=[3, {'path': '/srvs/hosting3/dir2'}]) => {
    "msg": {
        "path": "/srvs/hosting3/dir2"
    }
}
ok: [localhost] => (item=[4, {'path': '/srvs/hosting4/dir1'}]) => {
    "msg": {
        "path": "/srvs/hosting4/dir1"
    }
}
ok: [localhost] => (item=[4, {'path': '/srvs/hosting4/dir2'}]) => {
    "msg": {
        "path": "/srvs/hosting4/dir2"
    }
}

问题原因

问题出在变量渲染时机不匹配:
Ansible在加载Play的vars段时,会立刻尝试解析所有变量中的模板语法。但你定义的instance变量是在task的loop块里才创建的(属于task级临时变量),在Play加载vars阶段根本不存在,所以解析{{ instance }}时会找不到item(instance依赖item[0],而此时item还没生成),最终报错。

修复方案

方案一:使用路径模板,在循环时动态渲染

把目录路径定义为不带变量的模板字符串,在循环时用format方法替换实例索引:

- hosts: [localhost]
  vars:
    instances: [1,2,3,4]
    dir_templates:
    - "/srvs/hosting{instance}/dir1"
    - "/srvs/hosting{instance}/dir2"

  tasks:
    - debug:
        msg: "{{ item[1].format(instance=item[0]) }}"
      loop: "{{ instances | product(dir_templates) | list }}"

方案二:拆分路径固定部分与可变部分,循环时拼接

把目录的固定前缀、可变索引、后缀拆分,在循环时直接拼接生成完整路径,逻辑更直观:

- hosts: [localhost]
  vars:
    instances: [1,2,3,4]
    dir_suffixes:
    - "dir1"
    - "dir2"

  tasks:
    - debug:
        msg: "/srvs/hosting{{ item[0] }}/{{ item[1] }}"
      loop: "{{ instances | product(dir_suffixes) | list }}"

如果要实际创建目录,把debug模块换成file模块即可:

- file:
    path: "/srvs/hosting{{ item[0] }}/{{ item[1] }}"
    state: directory
  loop: "{{ instances | product(dir_suffixes) | list }}"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 14:56:07