Checking OS Version Across Multiple Hosts with Ansible

Often when you are maintaining a large number of servers, it is useful to be able to query those systems all at once to find out information like IP address, configured hostnames, and even the OS version.  

In this post we’re going to focus on pulling the OS version from multiple systems at once with a single Ansible playbook.  

First, lets get an idea of how our directory structure should look in the end, then we’ll break things down:

Ansible playbook and file-system layout:

[~/sources/ansible]
$ tree .
.
├── get-os-version.yaml
├── group_vars
│   └── linux
├── hosts
│   └── home
│   ├── archive.jbldata.com
│   ├── jbllnxwks.jbldata.com
│   └── yoga2.jbldata.com
└── host_vars

4 directories, 5 files

Now that we know how things should look in the end, lets setup our host configurations.

Host configurations:

[~/sources/ansible]
$ tree hosts/
hosts/
└── home
 ├── archive.jbldata.com
 ├── jbllnxwks.jbldata.com
 └── yoga2.jbldata.com

1 directory, 3 files

[~/sources/ansible]
$ cat hosts/home/archive.jbldata.com 
[linux]
archive.jbldata.com

As you can see, the host configurations can be fairly simple and straight-forward to start, following the directory structure outlined above. Now lets setup our group_vars.

Group configuration:

[~/sources/ansible]
$ cat group_vars/linux 
---
ansible_ssh_private_key_file: /home/jbl/.ssh/jbldata_id_rsa

In this case, each of the servers I’m dealing with are secured by password-protected SSH keys, so I’m setting up my group vars to reference the correct SSH private key to use when connecting to these servers.  Pretty simple so far?  Great, now lets look at the playbook.

The Ansible playbook:

[~/sources/ansible]
$ cat get-os-version.yaml 
---
- name: Check OS Version via /etc/issue
 hosts: linux
 tasks:
 - name: cat /etc/issue
 shell: cat /etc/issue
 register: etc_issue
 - debug: msg="{{etc_issue.stdout_lines}}"

This playbook is very simple, but does exactly what we need.   Here we are specifying the use of the ‘shell’ module in order to execute the cat command on our remote servers.

We use the ‘register’ keyword to save the resulting output of the command in a variable called ‘etc_issue’.  We then use the ‘debug’ module to print the contents of that variable via ‘etc_issue’.  

When executing a command via the ‘shell’ module, there are several return values that we have access to, which are also now captured in the ‘etc_issue’ variable. In order to access the specific return value we are interested in, we use ‘debug’ to dump the STDOUT return value specifically via ‘etc_issue.stdout_lines’.

Now we have an Ansible playbook and associated configuration that allows us to quickly query multiple servers for their OS version.

It’s important to note that since I’m using password-protected SSH keys, that I’m using SSH Agent before I execute the playbook.  This only has to be done once for repeated runs of the same playbook within your current terminal session, for example:

[~/sources/ansible]
$ ssh-agent 
SSH_AUTH_SOCK=/tmp/ssh-82DKhToCuPUu/agent.4994; export SSH_AUTH_SOCK;
SSH_AGENT_PID=4995; export SSH_AGENT_PID;
echo Agent pid 4995;


[~/sources/ansible]
$ ssh-add ~/.ssh/jbldata_id_rsa
Enter passphrase for /home/jbl/.ssh/jbldata_id_rsa: 
Identity added: /home/jbl/.ssh/jbldata_id_rsa (/home/jbl/.ssh/jbldata_id_rsa)

Now, we’re ready to execute the ansible playbook.  Here’s the resulting output:

[~/sources/ansible]
$ ansible-playbook -i hosts/home get-os-version.yaml 

PLAY [Check OS Version via /etc/issue] *****************************************

TASK [setup] *******************************************************************
ok: [jbllnxwks.jbldata.com]
ok: [yoga2.jbldata.com]
ok: [archive.jbldata.com]

TASK [cat /etc/issue] **********************************************************
changed: [yoga2.jbldata.com]
changed: [jbllnxwks.jbldata.com]
changed: [archive.jbldata.com]

TASK [debug] *******************************************************************
ok: [archive.jbldata.com] => {
 "msg": [
 "Ubuntu 14.04.3 LTS \\n \\l"
 ]
}
ok: [yoga2.jbldata.com] => {
 "msg": [
 "Ubuntu 14.04.5 LTS \\n \\l"
 ]
}
ok: [jbllnxwks.jbldata.com] => {
 "msg": [
 "Debian GNU/Linux 5.0 \\n \\l"
 ]
}

PLAY RECAP *********************************************************************
archive.jbldata.com : ok=3 changed=1 unreachable=0 failed=0 
jbllnxwks.jbldata.com : ok=3 changed=1 unreachable=0 failed=0 
yoga2.jbldata.com : ok=3 changed=1 unreachable=0 failed=0

And that’s pretty much it!  Now we just have to add more hosts under our hosts/ configuration, and we can query as many servers as we want from a single command.  Happy orchestrating!

Leave a Reply

Your email address will not be published. Required fields are marked *