Use restview to to make the Ansible rst documentation browsable

The ansible-doc package not only installs the command line tool but also some quite detailed Ansible documentation in rst format. It would be nice if it was browsable in a html format. Here’s how that can happen (Redhat/CentOS)

First install pip and restview

sudo yum install python-pip
sudo pip install restview

This will allow all hosts on your network to access the documentation at http://hostname:33333 if your firewall allows it.

restview /usr/share/doc/ansible-doc-2.7.5/rst/ --listen 33333 --allowed-hosts * &

Alternatively, if you’re on a desktop computer, use the following to launch a browser…

restview /usr/share/doc/ansible-doc-2.7.5/rst/ --browser

Hint: This might be useful for those taking the EX407 Ansible Exam assuming you can install these packages. Having this at your fingertips could prove to be very useful should something like how to structure a jinja2 template slip your mind.

There are a few rendering issues, resulting in broken links, but nevertheless there’s a lot of very useful information. I’ll update this if I get around to finding a solution for that (probably a restview alternative).  Here’s a few screenshots showing what’s provided…

ansible documentation ansible documentation ansible documentation ansible documentation

UPDATE: I took the Ansible exam and I now know this isn’t really needed. Ample easily used documentation is provided.

Create a space-separated list of play_hosts in Ansible

Sometimes I need a list of hosts as a string when working with Ansible. Pacemaker clustering is one example. Here’s a snippet of Ansible that does this..

    - name: Setup list of cluster hosts
        host_list: "{{ host_list }}{{ (play_hosts.index(item) == 0) | ternary('',' ') }}{{ item }}"
      loop: "{{ play_hosts }}"
      run_once: yes

This play will produce the following output;

ok: [cnode1] => {
    "host_list": "cnode1 cnode2 cnode4 cnode3"

If you need a different separator just change the second parameter in the ternary function. The below example produces a comma-separated list of play_hosts…

    - name: Setup list of cluster hosts
        host_list: "{{ host_list }}{{ (play_hosts.index(item) == 0) | ternary('',',') }}{{ item }}"
      loop: "{{ play_hosts }}"
      run_once: yes
ok: [cnode1] => {
    "host_list": "cnode1,cnode2,cnode4,cnode3"

Offset cron jobs with Ansible

Sometimes I want to run the same cronjob on a few hosts but I might want to offset them slightly if I’m accessing any shared resources. Here’s an easy way to do that, for a small number of hosts, using Ansible

- name: Ensure cron exists
    name: Test Job
    minute: "{{ play_hosts.index(inventory_hostname) }}-59/5"
    job: /usr/local/bin/ >> /var/log/log.log
    user: web

This would create a job, every 5 minutes, with a one minute offset compared to the previous host. So assuming four hosts we’d end up with the following cron job schedules;

hostname cron schedule Will run at minutes past the hour
host1 0-59/5 * * * * 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55
host2 1-59/5 * * * * 1, 6, 11, 16, 21, 26, 31, 36, 41, 46, 51, 56
host2 2-59/5 * * * * 2, 7, 12, 17, 22, 27, 32, 37, 42, 47, 52, 57
host4 3-59/5 * * * * 3, 8, 13, 18, 23, 28, 33, 38, 43, 48, 53, 58

For larger number of hosts it would probably be better to group hosts and run the offset via that.

ssh-copy-id automation with a list of hosts

Here’s another version of my ssh-copy-id script this time using a text file containing a list of hosts. The hosts file should contain a single host per line.


export SSH_USER="user"
read -s PASSWORD

while read HOST; do
            export HOST;
            expect -c '
            set SSH_USER $env(SSH_USER)
            set HOST $env(HOST)
            set PASSWORD $env(PASSWORD)
            spawn ssh-copy-id $SSH_USER@$HOST
            expect {
                        "continue" {
                                    send "yes\n";
                        "assword:" {
                                    send "$PASSWORD\n";
            expect eof'
            echo "Done $HOST"
done < "$1"

Execute the script and pass the path to the text file as a parameter. i.e.

./ /path/to/host/list.txt;

Creating a Vagrant, Virtualbox & Ansible environment in the Windows Linux Subsystem

I’ve just been given a new Windows corporate laptop, with a huge amount of RAM (64GB), a large number of cores, and I wanted to start using this as my main development virtualisation platform. I do a lot of stuff with Vagrant, Ansible and VirtualBox and Windows hasn’t always been a welcome home for this setup. A more welcoming experience can be received through the Windows Linux Subsystem (WLSS) and is a big improvement over Cygwin. The instructions here used Debian 9.5 but should work on many other Linux distributions with minor modifications (i.e. package manager).

First install Debian (or other distro) from the official instructions (easiest way is through the MS App Store).

Then update the OS…

sudo apt-get update && sudo apt-get upgrade;

The install Python and pip…

sudo apt install python;
sudo apt install python-pip;

Now Ansible can be installed through pip…

sudo pip install ansible

Next download Vagrant and install it…

wget "$VAGRANT";
sudo apt install ./$(basename "$VAGRANT");

If you’re behind a proxy you probably need this Vagrant plugin

vagrant plugin install vagrant-proxyconf;

Next install git…

sudo apt install git;

Finally we need to install VirtualBox. Don’t rush ahead and install the Linux version. I did and this and it does not work. Grab the latest Windows version and install that on the host system in the usual way.

Next back in the WLSS Debian shell we need to make a few modification to allow the Windows Version of VirtualBox to be used. Basically we allow Vagrant to access the Windows version of VB and set the proxy. Edit or delete these as necessary…

echo 'export VAGRANT_WSL_ENABLE_WINDOWS_ACCESS="1"' >> .profile
echo 'export PATH="$PATH:/mnt/c/Program Files/Oracle/VirtualBox"' >> .profile
echo 'export VAGRANT_HTTP_PROXY=${http_proxy}' >> .profile
source .profile

Next let’s clone a Vagrant / Ansible / Virtual project to test the setup out…

mkdir git && cd git;
git clone
cd Jenkins
vagrant up

This is one my own projects setting up a Jenkins instance. It’s fairly simple but it will test all components of the setup we have just installed.