Building a Magento Testing and Development Environment – Setup Ansible

Part 4, Setup Ansible

Ansible is a configuration management system.  It uses SSH and easy to understand scripts to make changes to a host or hosts with very little interraction from the admin.  It is perfect for small things like adding users, their SSH keys, and giving them sudo access.  Big things like installing and configuring Magento. It can be used to enforce policies like standard configurations. And can help speed up things like server installations and application roll-outs.

Ansible works over SSH.  It connects to the systems, uses sudo to get admin access, then makes changes that are detailed in playbooks.  Playbooks are files that list a set of steps for Ansible to perform like adding a user, editing a configuration file, or installing an update.

I am going to walk through the installation of Ansible and creation of a couple of simple playbooks. I am going to use the playbooks to distribute some users and their SSH keys to the servers we have created. I’ll show how to give some of those users sudo access. And finally I will show how to change the BASH history setting stored in .bashrc for each of the users to show how you might edit a file. Nothing too fancy but enough to give you an idea how to use Ansible and how powerful it can be. For more information you might consider the Udemy Mastering Ansible course or any multiple tutorials that can be found online.  For pre-built playbooks take a look at Ansible Galaxy, just be careful to test them in a sandbox before trying them in production.

So, lets get started.  First we are going to perform an apt update and upgrade.  Then we need to crease a user we will use as the ansible service account on all of our systems.  Then we’ll install ansible. So, SSH to your ansible server.

ssh ansible-server
sudo su -
apt update
apt upgrade
adduser ansiblesvc

Now we need to become the ansible service user so we can create a SSH key pair.  We’ll copy the public key to a directory our normal user has access to so it can easily scp it to the other servers.

su ansiblesvc
ssh-keygen -t rsa -b 4096 -C "ansiblesv@domainname.com"
exit
cp /home/ansiblesvc/.ssh/id_rsa.pub /home/user/ansiblesvc.pub
chown user:user /home/user/ansiblesvc.pub
After that we'll need to create that user on all of our servers and copy the public key to the authorized keys of that user, and grant the user sudo access. You can do that using the following "one-liner" script.  Simply change the name of the remote-server name to the correct name or ip, the user to your user, and the ansible-server to the hostname or ip of the ansible server.

ssh user@remote-servername << EOF
sudo su -
adduser ansiblesvc --gecos "Ansible Service Account,NA,NA,NA" --disabled-password
mkdir /home/ansiblesvc
mkdir /home/ansiblesvc/.ssh
scp user@ansible-server:/home/user/ansiblesvc.pub /home/ansiblesvc/
cat /home/user/ansiblesvc.pub /home/ansiblesvc/ >> /home/user/ansiblesvc.pub /home/ansiblesvc/.ssh/authroized_keys
echo "ansiblesvc ALL=(ALL) NOPASSWD:ALL" /etc/sudoers.d/ansiblesvc
chown ansiblesvc:ansiblesvc -R /home/ansiblesvc
chown root:root /etc/sudoers.d/ansiblesvc
exit
exit
EOF

You’ll need to repeat that above script for each of the servers.  If you’re smart you’ll create a shell script and replace the things that need to be changed with variables.  Regardless, once you are done the user ansiblesvc should be able to SSH to these servers and become sudo.

Now, let’s create the ansible playbook file structure. This is my structure, yours may be different, but this is just to give you an idea of how things work.  I create a directory under root called ansible.  Under there I create a directory called Files and another called Playbooks.  In the Files directory I put files that are probably common to all my scripts.  Under the Playbooks directory I create a new subdirectory for each playbook. So I have the following structure.

|____
|____files
|____playbooks
| |____newuser_and_sshkeys
| |____give_sudo
| |____history_set

In the ansible directory I have files that are lists of the hosts. I create all.hosts, magento.hosts, mysql.hosts, redis.hosts, utility.hosts, desktop.hosts, ubuntu.hosts, centos.hosts. In each file I put a list of the hostnames, one per line. This is the contents of a few of those files.

cat all.hosts

magento1
magento2
magentoredis1
magentoredis2
magentoutility1
magentoutility2
magentodb1
magentodb2
magentopc2
magentoapt1
magentomonitor1
magentologs1

cat magento.hosts

magento1
magento2

cat mysql.hosts

magentodb1
magentodb2

 

In the files directory I copy all of the public key files I have. I name those files authorized_keys.username.pub.

ls -lm1 /files

authorized_keys.johndoe.pub
authorized_keys.janedoe.pub
authorized_keys.playdoe.pub

Download the following scripts to the listed directory. Because the scripts are very sensitive to the spacing in the yml files I attached them to this post.  Simply save those files and remove the .txt from the name of the files.  Move the files into the following directories:

ansible/playbooks/newuser_and_sshkeys:
distributesshkeys.sh
username.sshkeymagento.yml

ansible/playbooks/give_sudo:
givesudohosts.sh
givesudo.sh
username.givesudo.yml

ansible/playbooks/history_set:
historyset.sh
username.historyset.yml

After copying these files you’ll need to make the .sh files executable after renaming them.

chmod +x ansible/playbooks/newuser_and_sshkeys/distributesshkeys.sh
chmod +x ansible/playbooks/give_sudo/givesudohosts.sh
chmod +x ansible/playbooks/give_sudo/givesudo.sh
chmod +x ansible/playbooks/history_set/historyset.sh

Now, let’s add a new user to all of the hosts.  We already have the SSH public key for John Doe so let’s create his user on all of the hosts.

/root/ansible/playbooks/newuser_and_sshkeys/distributesshkeys.sh johndoe all
PLAY [all] *********************************************************************

TASK [setup] *******************************************************************
ok: [magentoutility2]
ok: [magentoredis2]
fatal: [magento2]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh.", "unreachable": true}
ok: [magentoutility1]
ok: [magentoredis1]
ok: [magento1]
ok: [magentopc2]
ok: [magentodb1]
ok: [magentodb2]

TASK [group] *******************************************************************
ok: [magento1]
ok: [magentoutility1]
ok: [magentoredis1]
ok: [magentoutility2]
ok: [magentoredis2]
ok: [magentodb1]
ok: [magentodb2]
ok: [magentopc2]

TASK [user] ********************************************************************
ok: [magentoutility1]
ok: [magentoredis1]
ok: [magento1]
ok: [magentoutility2]
ok: [magentoredis2]
ok: [magentodb1]
ok: [magentodb2]
ok: [magentopc2]

TASK [Placing ssh key] *********************************************************
changed: [magento1]
changed: [magentoredis1]
changed: [magentoutility1]
changed: [magentodb1]
changed: [magentoredis2]
changed: [magentoutility2]
changed: [magentodb2]
changed: [magentopc2]
 to retry, use: --limit @/root/ansible/playbooks/newuser_and_sshkeys/johndoe.sshkeymagento.retry

PLAY RECAP *********************************************************************
magento1 : ok=4 changed=1 unreachable=0 failed=0 
magento2 : ok=0 changed=0 unreachable=1 failed=0 
magentodb1 : ok=4 changed=1 unreachable=0 failed=0 
magentodb2 : ok=4 changed=1 unreachable=0 failed=0 
magentopc2 : ok=4 changed=1 unreachable=0 failed=0 
magentoredis1 : ok=4 changed=1 unreachable=0 failed=0 
magentoredis2 : ok=4 changed=1 unreachable=0 failed=0 
magentoutility1 : ok=4 changed=1 unreachable=0 failed=0 
magentoutility2 : ok=4 changed=1 unreachable=0 failed=0

In this example the server magento2 was offline. But, if I check all of the servers I’ll see that the user johndoe has been created and the authorized_keys file has been setup.  John Doe should be able to SSH into the servers using only his SSH key.

If we want to add Jane Doe’s account to only the Magento servers we would use the following command:

/root/ansible/playbooks/newuser_and_sshkeys/distributesshkeys.sh janedoe magento

And, if we wanted to add Playa Doe to the MySQL servers and give him sudo access we would use the following commands:

/root/ansible/playbooks/newuser_and_sshkeys/distributesshkeys.sh playadoe mysql
/root/ansible/playbooks/give_sudo/givesudohosts.sh playadoe mysql

To see how this was executed open any of the .sh files.  You’ll see that the command line options we passed, the username and hosts file name, were used as variables in the script.  The script then used those variables to run the ansible-playbook executable with the yml file which contained the instructions.
Intro – Magento Development Environment
Part 1 – Installing Proxmox
Part 2 – Creating the Virtual Machines
Part 3 – Setup MySQL Master-Master
Part 4 – Setup Ansible
Part 5 – Setup APT Proxy

Leave a Reply