-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathupgrade_servers_send_report.yaml
158 lines (134 loc) · 5.86 KB
/
upgrade_servers_send_report.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
---
# Using Ansible server's facts as the authoritative source for date and time
- name: Playbook 1 - Gather facts for local Ansible server to get date and time
hosts: localhost
connection: local
gather_facts: yes
- name: Playbook 2 - Upgrade servers and generate reports
# hosts: select all hosts (all) or only a host subset/category
hosts: "{{ host_group | default('all') }}"
# become: true, privilege escalation
become: true
gather_facts: no
order: sorted
collections:
- ansible.builtin
- community.general
vars:
# CSS styling for navbar: menu width, failed/missing colors
nav_width: 220px
failed_style: 'color:orangered'
missing_style: 'color:grey;text-decoration:line-through'
# Email options
send_email: true
smtp_host: mail.yourcompany.com
smtp_port: 25
mail_from: "[email protected]"
mail_to: "[email protected],[email protected]"
mail_subject: "Ansible - Servers Upgrade Report"
# Uncomment these if authentication is required
#smtp_user:
#smtp_pass:
pre_tasks:
- name: Create reports/ folder to save reports
run_once: yes
delegate_to: localhost
file:
path: "./reports"
state: directory
# See jwkenney repo's README.md for an explanation of what is going on here.
# We set hosts as failed/missing until proven otherwise.
- name: Set initial job status to catch missing/failed hosts
set_fact:
job_success: False
missing: True
- name: Gather server facts and possibly weed out unavailable hosts
setup:
- name: Set remaining hosts as 'not missing'
set_fact:
missing: False
# Upgrade servers packages tasks
tasks:
- name: Update apt repositories and cache if older than one hour (Debian/Ubuntu)
apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
# You may use autoremove=yes to delete packages no longer needed
- name: Upgrade packages
apt: upgrade=dist force_apt_get=yes
register: upgrade_result
- name: List and save installed, upgraded or deleted packages
shell: grep -E "^$(date +%Y-%m-%d).+ (install|upgrade|remove) " /var/log/dpkg.log |cut -d " " -f 3-5
register: upgraded_or_removed_packages
when: upgrade_result.changed
- name: Check if reboot is needed due to kernel upgrade
register: reboot_required_file
stat: path=/var/run/reboot-required get_md5=no
- name: Reboot server (if kernel has been upgraded)
reboot:
msg: "Server reboot initiated by Ansible due to kernel upgrade"
connect_timeout: 5
reboot_timeout: 300
pre_reboot_delay: 0
post_reboot_delay: 30
test_command: uptime
when: reboot_required_file.stat.exists
post_tasks:
- name: Mark surviving hosts as 'successful'
set_fact:
job_success: True
# Saving curated lists of hosts as localhost facts, to make the Jinja loops easier to read in the template.
# To use: hostvars['localhost']['success_list'] , etc
- name: Save facts to Ansible server for kernel list, date/time, and success/failed/missing hosts
delegate_to: localhost
delegate_facts: True
run_once: yes
set_fact:
date_str: "{{ hostvars['localhost']['ansible_date_time']['date'] }}_{{ hostvars['localhost']['ansible_date_time']['time'] | replace(':','-') }}"
date_str_pretty: "{{ hostvars['localhost']['ansible_date_time']['date'] }} {{ hostvars['localhost']['ansible_date_time']['time'] }}"
kernels_list: '{{ hostvars | json_query(kernel_query) | unique | sort }}'
success_list: '{{ hostvars | dict2items | json_query(success_query) }}'
failed_list: '{{ hostvars | dict2items | json_query(failed_query) }}'
missing_list: '{{ hostvars | dict2items | json_query(missing_query) }}'
vars:
kernel_query: "*.ansible_kernel"
success_query: "[?value.job_success==`true`].key"
failed_query: "[?value.job_success==`false` && value.missing==`false`].key"
missing_query: "[?value.missing==`true`].key"
- name: Debug variables (-v)
delegate_to: localhost
run_once: yes
debug:
msg: "{{ item }}"
verbosity: 1
loop:
- "Success: {{ hostvars['localhost']['success_list'] }}"
- "Failed: {{ hostvars['localhost']['failed_list'] }}"
- "Missing: {{ hostvars['localhost']['missing_list'] }}"
- "Kernels: {{ hostvars['localhost']['kernels_list'] }}"
- name: Generate job report under ./reports/upgrade_job_report_{{ hostvars['localhost']['date_str'] }}.html
delegate_to: localhost
delegate_facts: True
run_once: yes
template:
src: job_report_master.j2
dest: "reports/upgrade_job_report_{{ hostvars['localhost']['date_str'] }}.html"
- name: Send email report from Ansible server (send_email={{ send_email }})
delegate_to: localhost
run_once: yes
when: send_email
mail:
host: "{{ smtp_host }}"
port: "{{ smtp_port }}"
username: "{{ smtp_user | default(omit) }}"
password: "{{ smtp_pass | default(omit) }}"
from: "{{ mail_from }}"
to: "{{ mail_to }}"
subject: "{{ mail_subject }}"
subtype: html
body: |
<p>See attached for a detailed job report.</p>
<p><strong>Successful hosts</strong>:<br><br>{{ hostvars['localhost']['success_list'] | join(' ') }}</p>
<p style="color:red;"><strong>Failed hosts</strong>: <br><br>{{ hostvars['localhost']['failed_list'] | join(' ') }}</p>
<p style="color:fuchsia;"><strong>Missing hosts</strong>: {{ hostvars['localhost']['missing_list'] | join(' ') }}</p>
<p><i>Generated by playbook {{ playbook_dir }}/job_report.yml on {{ hostvars['localhost']['date_str_pretty'] }}</i></p>
attach:
- "reports/upgrade_job_report_{{ hostvars['localhost']['date_str'] }}.html"