Combined use of shell script and ansible to update remote servers, divided to 3 groups.
shell script:
#!/bin/bash
TEMPLATE="update_ubuntu_template.yml"
PLAYBOOK="update_ubuntu.yml"
VAULT_OPTION="--ask-vault-pass"
ask_group() {
local group=$1
local default_response=$2
local response
read -p "Do you want to update/upgrade $group? ([Y] or Enter to accept, any other - to skip): " response
response=${response:-$default_response}
if [[ "$response" =~ ^[Yy]$ ]]; then
sed "s/{{ target_group }}/$group/" $TEMPLATE > $PLAYBOOK
ansible-playbook $PLAYBOOK $VAULT_OPTION
fi
}
ask_group "ubuntu_group1" "Y"
ask_group "ubuntu_group2" "Y"
# Special handling for ubuntu_group3 as we want to schedule reboot of this servers for midnight and not reboot it right now
read -p "Do you want to update/upgrade ubuntu_group3? ([Y] or Enter to accept, any other - to skip): " response
response=${response:-"Y"}
if [[ "$response" =~ ^[Yy]$ ]]; then
sed "s/{{ target_group }}/ubuntu_group3/" $TEMPLATE > $PLAYBOOK
ansible-playbook $PLAYBOOK $VAULT_OPTION --extra-vars "schedule_reboot=true"
fi
content of update_ubuntu_template.yml
- hosts: {{ target_group }}
become: true
become_user: root
tasks:
- name: Update apt repo and cache on all Debian/Ubuntu boxes
apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
- name: Upgrade all packages on servers
apt: upgrade=dist force_apt_get=yes
- name: Check if a reboot is needed on all servers
register: reboot_required_file
stat: path=/var/run/reboot-required
- name: Reboot the box if kernel updated
reboot:
msg: "Reboot initiated by Ansible for kernel updates"
connect_timeout: 5
reboot_timeout: 300
pre_reboot_delay: 0
post_reboot_delay: 30
test_command: uptime
when: reboot_required_file.stat.exists and not (schedule_reboot | default(false))
- name: Schedule reboot at 23:59 if kernel updated and scheduling is enabled
cron:
name: "Scheduled reboot for kernel update"
user: root
job: "shutdown -r now"
hour: 23
minute: 59
day: "{{ ansible_date_time.day }}"
month: "{{ ansible_date_time.month }}"
weekday: "*"
state: present
when: reboot_required_file.stat.exists and (schedule_reboot | default(false))
content of update_ubuntu.yml
- hosts: ubuntu_group3
become: true
become_user: root
tasks:
- name: Update apt repo and cache on all Debian/Ubuntu boxes
apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
- name: Upgrade all packages on servers
apt: upgrade=dist force_apt_get=yes
- name: Check if a reboot is needed on all servers
register: reboot_required_file
stat: path=/var/run/reboot-required
- name: Reboot the box if kernel updated
reboot:
msg: "Reboot initiated by Ansible for kernel updates"
connect_timeout: 5
reboot_timeout: 300
pre_reboot_delay: 0
post_reboot_delay: 30
test_command: uptime
when: reboot_required_file.stat.exists and not (schedule_reboot | default(false))
- name: Schedule reboot at 23:59 if kernel updated and scheduling is enabled
cron:
name: "Scheduled reboot for kernel update"
user: root
job: "shutdown -r now"
hour: 23
minute: 59
day: "{{ ansible_date_time.day }}"
month: "{{ ansible_date_time.month }}"
weekday: "*"
state: present
when: reboot_required_file.stat.exists and (schedule_reboot | default(false))
content of ansible.cfg
[defaults]
remote_user=user
inventory = /opt/ansible/ansible_servers.inv
interpreter_python = auto_silent
content of ansible_servers.inv
[ubuntu_group1]
server1
server2
server3
[ubuntu_group2]
server4
server5
[ubuntu_group3]
server6
server7
server8
group_vars/all.yml should have your user password in encoded form. Something like this:
# Default variables for all playbooks
ansible_become_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
encoded password here
ansible_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
encoded password here