Ansible
Ansible is an open-source automation tool. What that means is that you can use ansible to automatically do everything that you would normally do yourself on the server with the benefit that there is
no repetition - you write down what you want to do and ansible does it - to 1 or 100 servers
you don’t forget what you did
Ansible typically runs on your local computer and carries out tasks on a remote server. Ansible uses simple, human-readable scripts called playbooks to automate your tasks. So your job is to describe the state which a server should have - ansible will log into the system via SSH and ensures this state.
In this guide we will develop some examples so that you can get a feel of what the things above really mean.
Warnung
This guid will not help you install ansible. If you are on linux you can follow the official documentation. On Windows you either should use WSL (recommended) or you can try to run it using docker. You could also run the playbook from the server itself. Please discuss this with an administrator.
Basics
Let’s use ansible for the first time and learn the basic building blocks. Let’s make a quick introduction.
tasks
: These are (this might come as a surprise) tasks ansible will complete. An example of a task is: „Ensure that the directory XYZ exists“ or „Restart the service ssh.service“. There is a wide variety of pre-made tasks to choose fromvars
: Variables that you can use to define values, e.g. the name of a directory that should be created. Variables are defined per-host or per group of hostshosts
: The servers that ansible will control.
Hello World
Now we take what we learned and create a directory and file on our server. The file will be located at /tmp/ansible_testing/hello_world
.
Put the following code (your first ansible playbook) in a file called ansible-1.yml
- hosts: all
vars:
base_directory: "/tmp/ansible_testing"
tasks:
- file: path="{{ base_directory }}" mode=0700 state=directory
- file: path="{{ base_directory }}/hello_world" mode=0600 state=touch
You see two file
tasks there. The first one creates the direcotry /tmp/ansible_testing/
, the second creates the file hello_world
in there.
The directory location is here defined as variable. We can access this variable with the double-bracket syntax {{ var_name }}
. This will evaluate to /tmp/ansible_testing
.
We also need to tell ansible on which server these tasks should be executed. We use a inventory file for that. Create a file called hosts
with the following content.
intern.queereszentrumtuebingen.de ansible_user=root
If you created both files you can now execute the your first playbook with the ansible-playbook command!
ansible-playbook -i hosts --private-key=~/.ssh/KEY_NAME ansible-1.yml
-i hosts
is used to point the ansible-playbook command to the inventory file--private-key=~/.ssh/KEY_NAME
defines where your SSH key to the server is locatedansible-1.yml
is the playbook file
You can then verify that the file is correctly created on the server by logging in and executing
$ ls /tmp/ansible_testing
hello_world
Playbook structure
Most ansible roles are a lot more complex than our short hello_world. Therefor we will use a new structure of playbooks that will help you keep track of things.
A typicall playbook will have these parts:
* inventory
This is where we will define our hosts and the host_vars.
* roles
this directory has one or more roles that collect the tasks that will be executed
* setup.yml
this file will list all roles that should be executed for given server groups
The following is an example of a playbook. There are two hosts defined (qz1
and qz2
) with their respective vars.yml
. There is only a single role called static-server which
itself has various tasks attatched to it. LICENSE
and README.md
provide additional information on the playbook.
.
├── inventory
│ ├── hosts
│ └── host_vars
│ ├── qz1.queereszentrumtuebingen.de
│ │ └── vars.yml
│ └── qz2.queereszentrumtuebingen.de
│ └── vars.yml
├── LICENSE
├── README.md
├── roles
│ └── static-server
│ ├── defaults
│ │ └── main.yml
│ ├── tasks
│ │ ├── install.yml
│ │ ├── main.yml
│ │ ├── setup_site.yml
│ │ ├── uninstall.yml
│ │ └── validate_config.yml
│ └── templates
│ └── docker-compose.yml.j2
└── setup.yml
The setup.yml
for this playbook could look like this.
- name: "Set up a static server"
hosts: "static_site_servers"
become: true
roles:
- role: roles/static-server
and the inventory/hosts
like this
[static_site_servers]
qz1.queereszentrumtuebingen.de ansible_user=root
qz2.queereszentrumtuebingen.de ansible_user=root
There are a lot of examples which you can use as inspiration for playbooks. Here are some listed from easy to hard to understand
moanos/ansible-playbook-static-site-host: The example used above that set’s up a structure for a simple static site server.
moan0s/ansible-playbook-borgbackup-host: A similar playbook that set’s up a borgbackup host (place to store backups). We use this for our backup servers.
mother-of-all-self-hosting/mash-playbook: A somewhat complex playook that the QZT uses to set up most services
spantaleev/matrix-docker-ansible-deploy: A complex playook to set up a matrix server