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

Ansible:如何基于所有主机已注册facts修改变量并全局生效?

解决方法

核心要做的就是先汇总所有主机的settings_config状态,再基于整体结果判断邮件主题,不能只依赖单台主机的fact:

1. 汇总所有主机的变更状态

新增一个仅在本地执行一次的任务,收集所有目标主机的settings_config值,判断是否存在至少一台主机有变更(即settings_config不为false):

- name: 汇总所有主机的配置变更状态
  set_fact:
    any_host_changed: "{{ ansible_play_hosts | map('extract', hostvars, 'settings_config') | select('equalto', true) | list | length > 0 }}"
  delegate_to: localhost
  run_once: true

逻辑说明:

  • ansible_play_hosts:获取当前play中的所有目标主机
  • map('extract', hostvars, 'settings_config'):提取每台主机的settings_config变量
  • select('equalto', true):筛选出存在变更的主机(settings_config为true的主机)
  • 通过判断筛选结果的长度是否大于0,得到全局的变更标记

2. 基于全局状态设置邮件主题

修改原邮件主题设置任务,改用全局变更标记,同时修正原代码的拼写错误(sujectmail→subjectmail):

- name: 设置邮件主题
  set_fact:
    subjectmail: "{{ 'Ansible email Summary Status:green' if not any_host_changed else 'Ansible email Report Status: red!' }}"
  delegate_to: localhost
  run_once: true

3. 修正报告和邮件任务的变量引用

确保task10和task11使用正确的全局变量,同时修正原代码的文件路径变量错误(config_check_report_file→settings_report_file):

- name: task10 生成基础设施HTML报告
  template:
    src: "{{ settings_report_template }}"
    dest: "{{ settings_report_file }}"
  delegate_to: localhost
  run_once: true
  check_mode: no
 
- name: task11 发送邮件报告
  mail:
    host: "{{ mail_gateway }}"
    port: "{{ mail_gateway_port }}"
    sender: "{{ mail_sender }}"
    subtype: html
    to: "{{ mail_recipients }}"
    subject: "{{ subjectmail }}"
    body: "{{ lookup('file', settings_report_file) }}"
    secure: starttls
  register: mail_output
  delegate_to: localhost
  run_once: true
  check_mode: no

完整修改后的代码

# 此处放置原有的task01、task02等任务(需注册task01、task02的changed状态)

- name: Task05: 标记单主机无变更状态
  set_fact:
    settings_config: false
  when: task01.changed == false and task02.changed == false

# 新增的全局状态汇总任务
- name: 汇总所有主机的配置变更状态
  set_fact:
    any_host_changed: "{{ ansible_play_hosts | map('extract', hostvars, 'settings_config') | select('equalto', true) | list | length > 0 }}"
  delegate_to: localhost
  run_once: true

- name: 设置邮件主题
  set_fact:
    subjectmail: "{{ 'Ansible email Summary Status:green' if not any_host_changed else 'Ansible email Report Status: red!' }}"
  delegate_to: localhost
  run_once: true

- name: task10 生成基础设施HTML报告
  template:
    src: "{{ settings_report_template }}"
    dest: "{{ settings_report_file }}"
  delegate_to: localhost
  run_once: true
  check_mode: no
 
- name: task11 发送邮件报告
  mail:
    host: "{{ mail_gateway }}"
    port: "{{ mail_gateway_port }}"
    sender: "{{ mail_sender }}"
    subtype: html
    to: "{{ mail_recipients }}"
    subject: "{{ subjectmail }}"
    body: "{{ lookup('file', settings_report_file) }}"
    secure: starttls
  register: mail_output
  delegate_to: localhost
  run_once: true
  check_mode: no

关键说明

  • 原settings_config是单主机标记,仅代表当前主机是否无变更;新增的any_host_changed是全局标记,覆盖所有主机的变更状态
  • 所有全局变量的设置任务都添加了delegate_to: localhost和run_once: true,确保只执行一次,生成统一的全局结果
  • 同步修正了原代码中的变量拼写错误和文件路径不匹配问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 02:17:35