You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Ansible批量主机blkid检查后合并发送失败主机邮件求助

解决Ansible多主机blkid检查失败时汇总发邮件的问题

我来帮你搞定这个问题!你的核心困扰是当前每台失败的主机会单独触发一封邮件,这是因为原代码里的rescue块会在单个主机执行失败时立刻触发邮件发送逻辑。要实现「汇总所有失败主机发单封邮件」的需求,我们需要调整思路:先让所有主机完成检查,统一收集失败节点信息,最后在控制节点上一次性发送汇总邮件。

修改后的完整main.yml代码

- name: 执行所有主机的blkid检查
  hosts: all
  gather_facts: false
  tags: checkblkid
  tasks:
    - name: 运行blkid命令
      shell: /sbin/blkid
      register: blkid_result
      failed_when: blkid_result.rc != 0
      ignore_errors: true  # 关键:即使单台主机失败,也继续检查其他主机,不中断整个任务

- name: 发送失败主机汇总邮件
  hosts: localhost
  gather_facts: false
  tags: checkblkid
  tasks:
    - name: 收集所有blkid检查失败的主机
      set_fact:
        failed_hosts: "{{ groups['all'] | select('in', hostvars | dict2items | selectattr('value.blkid_result.failed') | map(attribute='key') | list) }}"

    - name: 当存在失败主机时发送汇总邮件
      mail:
        host: localhost
        to: xxxx@gmail.com
        subject: blkid检查失败主机列表
        subtype: html
        body: |
          <h3>以下主机blkid检查失败:</h3>
          <ul>
          {% for host in failed_hosts %}
            <li>{{ host }}</li>
          {% endfor %}
          </ul>
      when: failed_hosts | length > 0  # 只有有失败主机时才发送邮件

代码逻辑说明

  1. 第一阶段:全量执行检查

    • 针对所有主机执行blkid命令,用register记录每台主机的执行结果
    • ignore_errors: true确保某台主机失败时,Ansible不会终止整个任务,而是继续检查剩余主机
    • failed_when依然会标记执行失败的主机,方便后续筛选
  2. 第二阶段:汇总并发送邮件

    • 在控制节点(localhost)上,通过hostvars遍历所有主机的执行结果,筛选出blkid_result.failedtrue的主机
    • 用Jinja2模板在邮件正文中生成失败主机的HTML列表,让邮件内容更清晰
    • 添加when条件,只有存在失败主机时才发送邮件,避免发送空内容的邮件

对比原代码的改进点

原代码的rescue块属于单主机级别的错误处理,每台主机失败都会独立触发邮件发送;新方案是先完成所有主机的检查,再统一汇总失败信息,从「单主机触发」变成「全局汇总触发」,完美解决了多封邮件的问题。

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

火山引擎 最新活动