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

Ansible中如何合并同名include_vars变量避免覆盖

问题描述

现有Ansible剧本include.yaml内容如下:

#- name: "Playing with Ansible and Include files"
- hosts: localhost
  connection: local 
  tasks:
    - find: paths="./" recurse=yes patterns="test.yaml"
      register: file_to_exclude
    - debug: var=file_to_exclude.stdout_lines        
    - name: shell
      shell: "find \"$(pwd)\" -name 'test.yaml'"
      register: files_from_dirs     
    - debug: var=files_from_dirs.stdout_lines
    - name: Include variable files
      include_vars: "{{ item }}"
      with_items:
        - "{{ files_from_dirs.stdout_lines }}"
    - debug: var=files 

同时存在多个test.yaml文件:

  • ./dir1/test.yaml内容:
files: 
  - file1 
  - file2
  • ./dir2/test.yaml内容:
files: 
  - file3 
  - file4

当前执行剧本后,后导入的files变量会覆盖之前的,最终输出仅显示file3、file4。要求不修改test.yaml中的变量名,将所有files的值合并为[file1,file2,file3,file4]。


解决方案1:通过set_fact动态合并列表

修改原剧本,每次导入变量后将files列表追加到一个累计变量中:

#- name: "Playing with Ansible and Include files"
- hosts: localhost
  connection: local 
  tasks:
    - name: 查找所有test.yaml文件
      find: paths="./" recurse=yes patterns="test.yaml"
      register: test_files

    - name: 初始化合并列表为空
      set_fact:
        merged_files: []

    - name: 导入变量并记录结果
      include_vars: "{{ item.path }}"
      with_items: "{{ test_files.files }}"
      register: included_vars_result

    - name: 合并所有files列表
      set_fact:
        merged_files: "{{ merged_files + item.ansible_facts.files }}"
      with_items: "{{ included_vars_result.results }}"

    - name: 输出合并后的结果
      debug: var=merged_files

关键说明:

  • 用find模块的item.path直接获取文件路径,替代原剧本的shell命令,更符合Ansible最佳实践
  • 先初始化merged_files为空列表,避免首次合并时出错
  • 通过register捕获每次include_vars导入的变量,循环将每个文件的files列表追加到merged_files

解决方案2:用lookup插件直接读取合并

借助file lookup读取文件内容,解析后直接合并列表:

#- name: "Playing with Ansible and Include files"
- hosts: localhost
  connection: local 
  tasks:
    - name: 查找所有test.yaml文件
      find: paths="./" recurse=yes patterns="test.yaml"
      register: test_files

    - name: 合并所有files列表
      set_fact:
        merged_files: "{{ merged_files | default([]) + (lookup('file', item.path) | from_yaml).files }}"
      with_items: "{{ test_files.files }}"

    - name: 输出合并后的结果
      debug: var=merged_files

关键说明:

  • lookup('file', item.path)直接读取目标文件内容,from_yaml将内容解析为字典格式
  • 用default([])处理merged_files初始为空的情况,每次循环追加当前文件的files列表

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 08:18:34