Ansible
I looked for a deployment method for my ~800 Ubuntu nodes at work which would allow me to fully automate software deployments and manage configurations after an OS provisioning.
That’s how I met Ansible.
The tool has many benefits:
- No agent: it uses SSH.
- Playbooks are written in YAML which is human readable. As each tasks has a name, plays are auto documented.
- Idempotency: Ansible check if what you want is already done. Remove an inexistant file will not break your play.
- Modularity: tasks are grouped in roles
- Templating engine: with jinja2, you can factorize your configurations.
- Toolbox: dry-run/diff modes, secrets, tags, …
Tasks
To each kind of task correspond an Ansible module, file
, copy
, shell
…
It’s important to use native modules and to not use shell module for your tasks to keep idempotency.
---
- name: create resolv.conf
copy:
content: |
nameserver 1.1.1.1
nameserver 9.9.9.9
dest: /etc/resolv.conf
Playbooks, plays and inventory
A playbook is a yaml
file with a set of plays.
A play is a set of tasks and/or roles targetting a host/group from the inventory.
The inventory can be a static ini
or yaml
file or a dynamic inventory script, with hosts placed in groups.
[group1]
host1
host2
[group2]
host2
Roles
Tasks are grouped in roles, ansible-galaxy is a marketplace to share them.
A role has a specific structure:
roles/
common/
tasks/main.yml
handlers/main.yml
files/
templates/
[...]
tasks/main.yml
contains all tasks of the role.
handlers/main.yml
contains specific tasks which are triggered by passing notify
key to a task. If the tasks has a changed
status, then the handler will be run. Multiple notify will result at a single run at the end of the play.
# tasks/main.yml
---
- name: configure nginx
template:
src: templates/nginx.j2
dest: /etc/nginx/nginx.conf
notify: restart nginx
# handlers/main.yml
- name: restart nginx
service:
name: nginx
state: restarted
Managing dotfiles with Ansible
Managing my desktop recipe with Ansible allows me to deploy my setup over multiple hosts with specific configuration (dualscreen, packages…) by using jinja2 templating.
Centralizing my configurations on github is comfortable, I can pull my configuration from anywhere, and deploy it to all my managed nodes easily.
It also let me share my configurations with other linux users.
- https://github.com/eoli3n/arch-config/tree/master/ansible
- https://github.com/eoli3n/void-config/tree/master/ansible
I wanted my setup to be modulable at multiple levels. I use roles and inventory to be able to separate servers from desktops configuration.
Since I started to use Nixos, I separated my package management project from my dotfiles and added to each OS-projects my install scripts to automate provisioning process from the beggining.
I can use Nixos embeedeed automation process to configure the system, and push my dotfiles with ansible too in a second time.
As my configuration is fully managed, I can auto test at each push with a Continuous Integration tool : Travis-CI