Ansible中实现yum更新后合并多服务器告警邮件及报错排查求助
解决Ansible合并更新主机到单封告警邮件的问题
首先,咱们先搞定你遇到的错误:'ansible.vars.hostvars.HostVarsVars object' has no attribute 'yum_update'。这个问题的核心是在Ansible 2.9版本中,selectattr访问不存在的变量属性时会直接抛出错误,而非跳过对应主机——哪怕你的play里所有主机都执行了yum更新任务,也可能因为边缘场景(比如主机执行任务异常导致变量未注册)或变量同步小问题触发这个报错。
下面是修正后的完整playbook,完美实现所有更新主机合并到单封邮件的需求:
--- - name: Update enterprise template servers hosts: ent_template_servers tasks: - name: Update all packages yum: name: '*' state: latest register: yum_update - name: Reboot if needed import_tasks: /usr/share/ansible/tasks/reboot-if-needed-centos.yml - name: Kernel Cleanup import_tasks: /usr/share/ansible/tasks/kernel-cleanup.yml - name: Debug yum_update status per host debug: var: yum_update.changed - name: Send consolidated update alert email community.general.mail: to: - 'email@domain.com' subject: "Update Alert: {{ _changed | length }} system(s) updated" body: |- Updates have been applied on the following system(s): {% for host in _changed %} - {{ host }} {% endfor %} --- Generated by Ansible Tower sender: "ansible.updates@domain.com" delegate_to: localhost run_once: true when: _changed | length > 0 vars: # 先过滤存在yum_update变量的主机,再筛选更新过的主机 _changed: >- {{ hostvars | dict2items | selectattr('value.yum_update', 'defined') | selectattr('value.yum_update.changed') | map(attribute='key') | list }} ...
关键改动说明:
- 修复变量访问错误:新增
selectattr('value.yum_update', 'defined')先过滤出成功注册yum_update变量的主机,彻底避免因变量缺失导致的条件判断失败。 - 优化邮件可读性:主题加入更新主机数量,一眼就能掌握规模;用Jinja2循环生成清晰的主机列表,比直接打印原始列表更易读。
- 确保单封邮件发送:保留
run_once: true和delegate_to: localhost,确保整个play只在本地执行一次邮件任务,不管有多少台主机完成更新。
可选验证步骤:
如果你想先确认筛选出的更新主机列表是否正确,可以在邮件任务前加一个debug任务:
- name: Verify changed hosts list debug: var: _changed delegate_to: localhost run_once: true
这样调整后,你就只会收到一封包含所有更新主机的告警邮件,既解决了之前收到多封独立邮件的问题,也满足了你想要列出具体更新主机的需求。
内容的提问来源于stack exchange,提问作者ITMike89
相关产品推荐
相关产品推荐

