Ansible: How to Update Lots of Servers
So, usually I don't post snippets on the ol' blog, but sometimes I don't want to forget something—or in this case two somethings.
I've been using Ansible to manage servers at work, and it's been a fantastic tool. While I leave tons of stuff up to Puppet with respect to configuration and security management, it doesn't help out much with updating the servers.
So, without further ado:
Install Ansible
- First, install Ansible via the
pacman
command.sudo pacman -S ansible
- Honestly, it's not tough to set up. I usually place it in a directory like
~/Code/ansible
just to keep things straight.mkdir -p ~/Code/ansible cd ~/Code/ansible
- Create a subdirectory for the update playbook. We'll call it
update_servers
since it's catchy. I try to create a directory for every kind of playbook that I write.mkdir update_servers
Configure Hosts
For each server you want to update at the same time, ensure that you log into them via
ssh
. We're going to assume that you've set up each server to used shared keys to access them. This will ensure that each host in the list has had their key fingerprinted.You can get around this by disabling this key check in the
/etc/ssh/sshd_config
file, but I don't recommend it.ssh database.cerberus.local The authenticity of host 'database.cerberus.local (10.0.2.6)' can't be established. ECDSA key fingerprint is SHA256:7xMN0I07obwitJwBhxEEihkvLzvZhwScrM+kGXw1u/V. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'database.cerberus.local' (ECDSA) to the list of known hosts. Last login: Mon Jan 2 01:07:43 2017 from 10.0.0.155
Okay, now we add our hosts to a file named
hosts
. It's pretty simple to start with though it's pretty powerful.I'll label this server group as archlinux to keep 'em organized since I do have other Linux distros that I work with.
vim ~/Code/ansible/update_servers/hosts
[archlinux] webserver.cerberus.local database.cerberus.local ntp.cerberus.local
The Quick Update Playbook
Before I get hate-mail on this one, always research released packages before blindly running updates. I'm lazy as I have more than three Arch Linux servers to update at a time, but even I verify that there isn't going to be a catastrophe when I update.
Also, I don't recommend doing this if you have very, very complicated builds. I do recommend using Ansible, but maybe not using it to update if it's that complicated.
- Navigate to the
update_servers
directory if you're not already there. We're gonna build a YAML file!cd ~/Code/ansible/update_servers
- Open up your favorite editor, and create the
update_servers.yaml
file. This is where the magic happens. We're going to use thepacman
module that comes with Ansible to accomplish everything.vim update_servers.yaml
In the YAML content below, it should be pretty self-explanatory. The hosts line pulls the group of servers out of the inventory file via the label we used. The become line allows us to escalate privileges on the servers after we log in.
The
pacman
tasks tell it to update the package cache before actually updating. I like breaking up the command so I know exactly where the process fails at. A few more lines, but a bit more informationEdit the pertinent parts below, and save it.
# vim:ts=2:sts=2:sw=2:et
- hosts: archlinux
remote_user: jweatherly
become: true
tasks:- name: Update 'pacman' cache
pacman:
update_cache: true - name: Update Arch Linux via 'pacman'
pacman:
upgrade: yes
- name: Update 'pacman' cache
- hosts: archlinux
Running Updates
Using the ansible-playbook
command, lets kick the tires on our new playbook.
cd ~/Code/ansible/update_servers
ansible-playbook -i hosts -K update_servers.yaml
SUDO password:
PLAY [arch] ********************************************************************
TASK [setup] *******************************************************************
ok: [database.cerberus.local]
ok: [webserver.cerberus.local]
ok: [ntp.cerberus.local]
TASK [Updating 'pacman' cache] ******************************************
changed: [webserver.cerberus.local]
changed: [database.cerberus.local]
changed: [ntp.cerberus.local]
TASK [Upgrading Arch Linux via 'pacman'] ****************************************************
ok: [database.cerberus.local]
ok: [webserver.cerberus.local]
ok: [ntp.cerberus.local]
PLAY RECAP *********************************************************************
database.cerberus.local : ok=3 changed=1 unreachable=0 failed=0
webserver.cerberus.local : ok=3 changed=1 unreachable=0 failed=0
ntp.cerberus.local : ok=3 changed=1 unreachable=0 failed=0
If everything was typed in correctly, then you should see ansible-playbook
log into each server, grab some information, then start in on the tasks defined in the update_servers.yaml
file.
The -i
option allows you to specify an inventory file. The -K
option tells ansible-playbook
to use sudo to elevate privileges. You can also use the -k
option to specify a password to login to the target servers. This will only work if you've installed the sshpass
package, and hopefully all of your servers have the same password associated with the user account you're using—basically the reason I use keys.