如何用Ansible基于列表动态生成Docker挂载字典列表?
正确生成Docker挂载列表的Ansible实现方法
现有资源与需求
已定义变量
- 挂载点列表:
mpoints: ['/home/mp1', '/home/mp2', '/mnt/mp1', '/mnt/mp2']
- 根目录变量:
vars: rootdir: '/var/tmp'
目标需求
为mpoints中的每个元素生成对应挂载字典,组成new_list,每个字典格式如下:
{ source: "/home/mp1", target: "/var/tmp/home/mp1", type: bind, read_only: no }
最终将new_list作为community.docker.docker_container模块的mounts参数使用。
错误尝试分析
你之前的写法存在三个问题:
- 嵌套模板语法错误:Jinja2模板内无需再嵌套
{{ }},直接引用变量名即可 - 循环变量名错误:应该使用
mpoints而非mpoint - 初始变量未定义:第一次循环时
new_list不存在,会触发报错
错误代码:
set_fact: new_list: "{{ new_list + [{ source: "{{ item }}", target: "{{ rootdir }}/{{ item }}", type: bind, read_only: no }]}}" loop: {{ mpoint }}
正确实现方法
方法一:循环追加生成列表
先初始化空列表,再逐个追加挂载字典:
- name: 初始化挂载列表 set_fact: new_list: [] - name: 生成每个挂载点的字典条目 set_fact: new_list: "{{ new_list + [{'source': item, 'target': rootdir ~ item, 'type': 'bind', 'read_only': false}] }}" loop: "{{ mpoints }}"
注意事项:
- 字典键需加引号,避免YAML解析歧义
- 字符串拼接用
~(比+更适配字符串场景) read_only使用布尔值false,符合Docker模块参数规范
方法二:Jinja2列表推导式(简洁版)
无需循环步骤,直接用模板语法一次性生成列表:
- name: 直接生成挂载列表 set_fact: new_list: >- {% set mounts = [] %} {% for item in mpoints %} {% do mounts.append({'source': item, 'target': rootdir ~ item, 'type': 'bind', 'read_only': false}) %} {% endfor %} {{ mounts }}
最终使用示例
将生成的new_list传入Docker容器模块:
- community.docker.docker_container: name: nginx image: nginx state: started pull: true detach: yes tty: yes restart_policy: always ports: 80 mounts: "{{ new_list }}"
内容的提问来源于stack exchange,提问作者Felipe Diefenbach
相关产品推荐
相关产品推荐

