Automatically update multiple VPS with Ansible

ansible-logoOver time the number of VPS’s I manage has increased. Until recently I logged in manually to each server to update the software. But with the increasing number of VPS’s this started to get tedious. So I decided to look into a way to automate this, and I decided to use Ansible. In this post I will share my current setup. I will assume you are somewhat familiar with Ansible, but if you are not you can take a look at this tutorial on to learn more about Ansible. If you rather have a video tutorial they also have you covered, in that case you can take a look at this free series.

Because all my servers run Ubuntu 14.04 I can update them all with the same commands, which makes things easy because I can simply use a single playbook to do just that. Because it seemed likely that somebody else had already tackled this problem before I turned to Google to look for a playbook, and I found this post by Chao Huang. In his posts he describes an Ansible playbook that updates all the software on Debian/Ubuntu based systems and also reboots the server after updating if this is necessary. So that’s what I use:

# Upgrade Debian/Ubuntu based systems and reboot if necessary.
 - hosts: 
   sudo: yes
     - name: Check if there are packages available to be installed/upgraded
       command: /usr/lib/update-notifier/apt-check --package-names
       register: packages
     - name: Upgrade all packages to the latest version
       apt: update_cache=yes upgrade=dist
       when: packages.stderr != ""
     - name: Check if a reboot is required
       register: file
       stat: path=/var/run/reboot-required get_md5=no
     - name: Reboot the server
       command: /sbin/reboot
       when: file.stat.exists == true

On all my servers I use the same user to login, but this user does have to use sudo to run some of the commands in the playbook above. My servers are also configured so that a user has to provide a password to use sudo. So I needed a way to provide this password to Ansible. However, because I am not that familiar with Ansible this turned out to be more difficult than I expected, mostly because I did not want to store the sudo passwords in cleartext. But after some experimenting I figured out an approach that works quite well. In my current setup I use host variables to specify the sudo password for each of my servers, and I use Ansible Vault to encrypt the passwords.

If you want to specify host variables for the host you can create the file /etc/ansible/host_vars/ and add your variables to it. These variables will then be used for that host in any playbook you run. So in my setup I create a host variables file for each of my servers and specify the sudo password in it:

ansible_become_pass: PASSWORD

To encrypt these files with Ansible Vault you have to create them with the following command:

ansible-vault create /etc/ansible/host_vars/

This command will ask you for a password, make sure you use the same password for all your host variables files. You need to use the same password for all host variables files, because you can specify only one Ansible Vault password when running playbooks.

With sudo passwords specified for all my servers I can now update them all with a single command:

ansible-playbook playbook.yml --ask-vault-pass

If you have any suggestions or questions just leave a comment below.

December 12, 2015

Click Here to Leave a Comment Below

Leave a Reply: