As our infrastructure is growing, the number of services and tasks is increasing as well. This can be tedious and time-consuming, especially when you have to deal with a lot of servers - enter
Ansible! Ansible allows automating tasks on a wide range of platforms, including Linux, Windows, and Mac. It is based on so-called playbooks, roles and tasks. Once defined, it is really easy to deploy the defined settings to target machines. All it needs is adding a few lines to the
hosts file and defining
host_vars to let Ansible know what kind of tasks to execute.
Starting out #
As I didn’t know much about Ansible before, I decided to study already existing playbooks in order to learn more about how it works. The Arch infrastructure repository helped me a lot in understanding how to set up the different roles needed. I began by writing a role for all kinds of common tasks like installing base packages, setting up services and installing a MOTD.
Host_vars and conditionals to the rescue #
Since not every host needs to be configured the same way,
host_vars provides a neat way to define what task to execute on which machine. I also added a few conditionals to the role to make sure that certain tasks are only executed if needed - eg. Chaotic-AUR GPG keys don’t need to be fetched every time the playbook is executed. There was also one issue with our
docker-compose configurations - as the repo was closed source previously, it contained a lot of sensible environment variables in those files. To make it open source, those variables needed to be replaced with Ansible variables. Thanks to the
template feature of Ansible, it is quite easy to supply a template
docker-compose.yml.j2 (Jinja2 formatting) which then gets rendered into a proper
docker-compose.yml file with the variables replaced when the playbook is executed. Also,
ansible-vault is a great little tool that allows encrypting sensitive files and data easily - Ansible automatically decrypts the content when deploying changes.
Automating everything! #
While writing the different roles, I had so much fun that I couldn’t stop working on it until it was all automated. Ansible Galaxy also came in handy, as it provided an already existing playbook for basic hardening of Linux installations and SSH with the devsec.hardening collection. Meanwhile, I also rewrote our existing Nginx configurations to better fit our needs. Thinking about how I used Nginx Proxy Manager to handle web server needs not too long ago, I’m somewhat happy I finally learned how to do it properly. It just provides so much more flexibility concerning configurations and setup. While NPM worked fine for the time being, it feels really good to be able to write your own Nginx configurations!
Chaotic-AUR cluster bootstrap? #
Well, since I’m also operating Chaotic-AUR, it was natural to also include it in the process of automating stuff. After a long trial and error session, the
chaotic_aur role is now available on Chaotic’s
Github organization. It is also available in Garuda’s infrastructure repository as a git submodule and can be used to set up a whole cluster if provided with the correct
Throwing in some GitLab CI #
Automating and running playbooks on my personal machine was too boring, so I decided to utilize GitLab CI to
trigger deployments based on commit messages. Currently, the repo responds to
deploy <playbook.yml> as well as
dry-run <playbook.yml>. Obviously
deploy deploys the supplied playbook while the latter initiates a dry run via
ansible-playbook <playbook.yml> --check.
Wrapping it all up #
I had a great time learning how to use Ansible! It will be really useful to decrease time spent configuring servers, allowing me to focus on other things which aren’t automated. After all, changes just need to be pushed by
ansible-playbook full_run.yml while setting up a new server became a matter of a few minutes.
There's no articles to list here yet.