Ansible高级循环操作的核心是通过字典列表传参、条件判断、自定义变量名和结果解析,实现一次定义、多次执行的批量配置管理。

Ansible 高级循环操作的核心,是把“多个相似配置项”变成“一次定义、多次执行”,避免重复写任务、硬编码路径或手动拼接变量。关键不在于循环本身有多复杂,而在于如何让循环适配真实运维场景中的多维参数、条件跳过、错误处理和结果提取。
用字典列表传参,一次定义多组配置
批量修改配置常涉及不同服务、不同路径、不同替换内容。硬写多个 task 不可维护,用字典列表 + loop 就能结构化表达:
- 每个字典代表一项独立配置:包含目标文件、要替换的正则、新内容、是否备份等字段
- task 中直接引用 item.path、item.regexp、item.replace,语义清晰
- 示例:
- name: 批量更新服务配置
ansible.builtin.replace:
path: "{{ item.path }}"
regexp: "{{ item.regexp }}"
replace: "{{ item.replace }}"
backup: true
loop:
- { path: "/etc/nginx/nginx.conf", regexp: "worker_processes.*;", replace: "worker_processes auto;" }
- { path: "/etc/redis/redis.conf", regexp: "^#?maxmemory.*", replace: "maxmemory 2gb" }
加条件判断,跳过不满足前提的项
不是所有配置都需要改——比如只在特定 OS 或已存在文件时才执行。loop 本身不带条件,但可结合 when 实现精准控制:
- when 放在 task 级,每次循环都会单独判断
- 可用 item 字段、facts(如 ansible_facts['distribution'])、注册变量做判断依据
- 例如:仅当文件存在且系统为 CentOS 8 时才修改 sshd 配置
- name: 条件化更新 SSH 配置
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
line: "ClientAliveInterval 300"
state: present
when:
- item.path | file_exists
- ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "8"
自定义循环变量名,提升可读性与嵌套兼容性
默认用 item 没问题,但遇到多层 loop(比如外层遍历服务、内层遍历该服务的配置项)时容易混淆。用 loop_control: loop_var 明确命名:
- 外层循环变量设为 service,内层设为 config
- 模板中写 {{ service.name }} 和 {{ config.key }},一目了然
- 特别适合处理 YAML 嵌套结构或 lookup 返回的复杂数据
- name: 为每个服务应用其专属配置集
ansible.builtin.template:
src: "templates/{{ service.template }}.j2"
dest: "{{ service.config_path }}"
loop: "{{ services }}"
loop_control:
loop_var: service
注册并解析循环结果,实现后续校验或汇总
批量修改后,往往需要检查哪些成功、哪些失败、输出是否符合预期。关键点是:注册变量存储的是整个循环的结果对象,真正数据在 results 列表里:
- 用 register: replace_result 捕获全部执行记录
- 后续 task 遍历 replace_result.results,每个元素含 changed、stdout、rc 等字段
- 可统计失败数、提取变更路径、生成报告,甚至触发告警
- name: 检查哪些配置被实际修改
ansible.builtin.debug:
msg: "Updated {{ item.item.path }}"
loop: "{{ replace_result.results }}"
when: item.changed

















