Ansible is an automation platform that can be used for provisioning, configuration management, and deployments. It does not require deploying an agent and is suitable to manage any system that allows SSH connections and can run Python 2.7.
Ansible is very powerful for fleet management. Currently, many IT organizations espouse a “cattle not pets” or “stamps not snowflakes” mode of managing in their IT. If your servers are pets, you lovingly create each one by hand, tweaking and tuning it to its specific purpose. This is fine if you have 10 servers but does not scale well. If your servers are cattle, you can create them by the dozen, with the idea that you manage each system identically with common policies.
For managing your own personal LEBs, Ansible can accomplish several things:
- Taking the drudgery out of common setup tasks, such as installing packages, tweaking config files, installing creature comforts in dot-files, setting up software, etc.
- Enforcing policies so that systems don’t “drift” from your standard configs.
- Automating routine tasks such as updating systems, deploying new software, etc.
This tutorial will not attempt to cover everything that Ansible can do, but rather show you how you can quickly make managing your LowEndEmpire more pleasant.
In part one, we’re going to introduce some Ansible concepts and get Ansible setup on your control node (the master). In the next tutorial we’ll use Ansible to manage some hosts.
Ansible Terminology
Control Node: the host that serves as a master, dispatching tasks to other hosts (or itself)
Host (or node): a remote machine that Ansible manages
Roles: you will assign roles to a host or group of hosts, such as “webserver” or “database server” to manage them. A host can have many roles.
Playbooks: these contain a list of plays (think sports), which are rules that say “run these tasks on these hosts”. A task in this context can be something like “update packages” or “copy this file”. Typically you’ll run a playbook, which says “for this group of hosts, run these sets of tasks”.
The Name Ansible Itself: Science fiction author Ursula LeGuin created the word “ansible” to describe a means of high-tech superliminal communication equipment, where messages can be exchanged nearly instantly even over interstellar distances.
There are many more terms but these are enough to get us started.
Setting Up An Ansible Control Node
In this tutorial, we have a control node called master, and a target called (wait for it…) target. Both are going to run Debian 10, but of course Ansible can run on many operating systems.
First, add the following line to /etc/apt/sources.list so you pick up the Ansible repo:
deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main
Then run these commands as root:
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367 apt update apt install ansible
Setting Up An Ansible SSH Key
Since everything Ansible does is done over ssh, we’ll want to create an ssh key. You can either generate a passwordless ssh key or use ssh-agent.
In this example, I’m running my control node from a secure location – my home, safe behind a NAT’d firewall – so I’ll be using passwordless ssh.
If your control node is in the cloud, you may not want to use a passwordless ssh key because if your control node is compromised, then all of the nodes that ansible controls could be compromised as well. In that configuration, an ssh-agent setup where you need to enter a password to kick off Ansible may be preferable.
To generate an passwordless ssh-key, issue the following command, answering with a return when prompted for no password:
ssh-keygen -t ed25519 -f ~/.ssh/ansible-key -C 'ssh key for ansible'
Setting Up the Ansible Target Node(s)
There’s no software to install, but you do need to setup the ssh key. Some VPS providers allow you to run a script as part of your setup. If so, putting your Ansible ssh key into root’s authorized_keys is easy to go. If your provider doesn’t offer this functionality, then you’ll need to setup the SSH key manually.
Here is a script that can be used to ensure that the Ansible key is setup properly. You can either run it as a setup script in your provider’s provisioning, or you can copy it to your target node and run it there. You could even login to your target node, copy/paste this script to a file in /tmp, and then execute it. Be sure to change the SSH key (where it says YOUR SSH PUBLIC KEY) to match your control node’s public key.
#!/bin/bash set -e # will exit on any error [ ! -d /root/.ssh] && mkdir /root/.ssh [ ! -f /root/.ssh/authorized_keys] && touch /root/.ssh/authorized_keys echo "YOUR SSH PUBLIC KEY" >> /root/.ssh/authorized_keys chown root:root /root/.ssh/authorized_keys chmod 600 /root/.ssh/authorized_keys chown root:root /root/.ssh chmod 700 /root/.ssh echo "Ansible ssh key setup successfully"
Setting Up Inventory
We need to give Ansible a list of hosts to manage. We can also use list this to define groups.
In this case, ‘target’ is going to be a database host. So we’ll edit /etc/ansible/hosts to create a ‘db’ group and put ‘target’ into it:
[db] target.example.com
Look at the examples (commented out) in /etc/ansible/hosts to get a feel for how you can group hosts and specify them.
Setting Up ansible.cfg
You’ll want to modify /etc/ansible/ansible.cfg (the main Ansible options file). If you use the default Ansible file locations, you’ll have less to modify, so here I will just call out some options to consider.
If you’ve changed the SSH port on your target hosts, you can use the remote_port setting to change this. For example, if you use port 32222, change this line in the [defaults] group:
remote_port = 61941
You may wish to disable host key checking, otherwise you’ll need to either use ssh-keyscan to add new hosts to your control node’s known_hosts or manually answer ‘Y’ the first time a playbook is run:
host_key_checking = False
Finally, you need to tell Ansible which private key to use, so be sure to set this option:
private_key_file = /root/.ssh/ansible-key
Setting Up an Ansible Working Directory
You’ll want on a work area on your control node for ansible, where you can:
- keep playbooks and plays
- keep various source files you want to distribute to your target nodes. For example, you might have a vimrc.local you want to always have on your hosts. To do this, create a directory that will hold all your source files. It can be anywhere you wish.
In this tutorial, we’ll keep it simple and call the work directory /ansible, and keep any files we want to distribute in /ansible/src
mkdir -p /ansible/src
Next Time
Now that we’ve got Ansible setup, we’ll show you how to exploit its capabilities in the next tutorial.
Related Posts:
- Crunchbits Discontinuing Popular Annual Plans – The Community Mourns! - November 20, 2024
- RackNerd’s Black Friday 2024: Bigger, Better, and Now in Dublin! - November 19, 2024
- It’s the Season of Giving and CharityHost Has Deals for You! - November 18, 2024
That was a good read raindog. I’ve always been a fan of doing these sorts of things manually, but with black friday coming and the staggering collection of servers I have growing these days, I might look into ansible to keep them all “in sync” :)
This could be an interesting way to make sure that all my BF idlers are going to be idling the exact same way lol
I love people with staggering collections of servers LOL
I use Ansible to deploy 25 VPSes (mostly LowEndBoxes) all around the world for https://dnstools.ws/. It works pretty well! My Ansible config is open-source if you’re interested: https://github.com/Daniel15/dnstools/tree/master/ansible
Note that Python 2.7 is EOL now. Everyone should be using Python 3.x in production.
Thank you for this nice tutorial. I have a couple of comments in the spirit of open source, sharing and learning together.
This tutorial is from 2020, trusty is EOL. Xenial and later have ansible OOTB, thus I think you should seriously consider to remove the line with the PPA.
Secondly, one of the core principles of ansible is idempotency. The script to add your ssh key to authorized keys is not idempotent. I’ve published my version at https://github.com/leggewie/devops/blob/main/firstrun-add-sshkey-for-root.sh
I’d also like to make you guys aware of an ansible role that I created that comes in handy for lowend VPS. Oftentimes, they are very low on RAM, to the point where ansible crashes. The way I deal with this is to automatically stop RAM-hungry services at the very beginning and restart them towards the end.
https://gitlab.com/leggewie/devops/-/tree/master/roles/lowmem
Thanks for sharing.
Thank you for the article. Very helpful.