Programster's Blog

Tutorials focusing on Linux, programming, and open-source

How I Set Up Ansible Master / Slave

This is a guide as to how I set up my Ansible server (once installed) and it's slaves, to make it easy to add slaves in future. This is just how I do things, which does not have to reflect how you use Ansible as there are many different ways you can secure your setup.

Setting up Master Ansible Server

Log into your ansible server and set up a user called ansible. This will be the user that uses the Ansible tool to log into all of the other servers to control them, so set a strong password and perhaps set up two-factor authentication.

sudo adduser ansible

Add the user to the sudo user group.

sudo adduser ansible sudo

Create SSH Key

Log in as the ansible user and create a key for them. We will be using this key for logging into the other servers later as the ansible user, so it is important that it is kept secure and never copied/transferred out of the server. We will not be setting a passphrase on this key for the convenience of the server never having to require a password when we tell it to update the other servers. Our security depends on this server not being compromised, which is why it is important that this server is only responsible for using Ansible (e.g. don't set it up to also be an FTP server etc), and strong security is used for acessing it (two factor etc).

su ansible

Recommended - Delete Original User

I would go ahead and remove the original account at this point (the one that you logged in with to create the ansible user), so we always only log into this server as the ansible user.

Setting Up Remote Servers

The hassle with Ansible is going through the steps of allowing the remote server to be controlled by ansible. Run the script below to set up an ansible user on the host with a temporary password.

Ensure you have python installed on the server so Ansible can work with it. AWS Ubuntu instances appear to deploy without any verson of Python having been installed.

if ! [ -n "$BASH_VERSION" ];then
    echo "this is not bash, calling self with bash....";
    SCRIPT=$(readlink -f "$0")
    /bin/bash $SCRIPT

PASSWORD=`date +%s | sha256sum | base64 | head -c 32 ; echo`
ENCRYPTED_PASSWORD=$(openssl passwd -1 ${PASSWORD})
sudo useradd -m -p $ENCRYPTED_PASSWORD ansible
sudo adduser ansible sudo

# Ensure the server allows password based access
# Required for the next step, but can disable later.
SEARCH="PasswordAuthentication no"
REPLACE="PasswordAuthentication yes"
sudo sed -i "s;$SEARCH;$REPLACE;" $FILEPATH

# Restart the SSH service for change to take effect.
sudo service sshd restart

# Give the ansible user passwordless sudo
echo 'ansible ALL=(ALL) NOPASSWD: ALL' | sudo EDITOR='tee -a' visudo

echo "Ansible user created with the password: $PASSWORD"

Use the outputted password for the next script that you need to execute on your ansible host.

ssh-copy-id [new slave server IP]

Your ansible server now has the ability to manage the remote server. Don't forget to add the slave to the relevant sections in your ansible hosts file if you already have some playbooks set up.

Optional - Disable Password Based Access

For these steps to work, the script that ran on the slave had to enable password based access. If you wish to only use SSH keys to access the remote host, then you can disable passwords again by executing this on the slave.

SEARCH="PasswordAuthentication yes"
REPLACE="PasswordAuthentication no"
sudo sed -i "s;$SEARCH;$REPLACE;" $FILEPATH
sudo service sshd restart

If you are setting up a fleet of servers at once, you may wish use ansible to disable password based access on all the servers at the very end, but creating a local script that it will execute on the remote servers.

Last updated: 8th January 2023
First published: 16th August 2018