Ansible est une solution de provisionnement écrite en Python qui s’utilise avec des fichiers YAML. Ces fichiers sont organisés en respectant une certaine structure appelée playbook. Ça fait un peu plus de 5 ans que je m’en sers pour MD ou pour nos clients. Tout est versionné via Git. Ça requiert uniquement Python sur le serveur cible. Bref, ça fait le job et ça le fait bien.
Si vous voulez en savoir plus sur Ansible, je vous invite à lire cette présentation en français. Si vous n’avez pas le temps de la lire, les seuls concepts d’Ansible à comprendre pour continuer la lecture de cet article sont :
Dans un avenir proche, je vais avoir besoin du moteur de recherche MeiliSearch sur un de mes serveurs (pour le blog de Maylis, ainsi que pour mon projet Stargazer — dont je parlais dans un précédent article).
Pour installer MeiliSearch, j’ai plusieurs possibilités :
Via APT, ça pose un problème de dépendances. N’ayant pas envie de creuser davantage j’ai laissé tomber cette solution. Le coup du binaire posé quelque part sur le serveur, c’est gérable facilement avec Ansible mais ça m’ennuie un peu de gérer ça comme ça. Après (cette super longue) réflexion, je vais donc partir sur Docker. En effet Docker n’est toujours pas installé sur mon serveur et j’ai plein d’autres services dockerizables à tester, donc ça m’arrange.
Pour installer Docker, j’ai choisi d'écrire mon propre rôle plutôt que d’en utiliser un provenant d’Ansible Galaxy (le site de partage de rôles de la communauté Ansible). Comme tout paquet / librairie, dans certains cas il est intéressant d’en utiliser pour gagner du temps (tant que l’on fait confiance à l’auteur), tandis que dans d’autres cas il est préférable de faire le boulot soi-même. Donc sans plus attendre, le roles/docker/tasks/main.yml
de mon rôle Docker, qui est une simple traduction en YAML de la documentation d’installation de Docker sur Ubuntu :
- name: Install Docker dependencies
apt:
state: latest
update_cache: yes
name: ['apt-transport-https', 'ca-certificates', 'curl', 'gnupg-agent', 'software-properties-common', 'python-pip']
- name: Add Docker's official GPG key
apt_key:
url: https://download.docker.com/linux/ubuntu/gpg
state: present
- name: Add Docker Repository
apt_repository:
repo: deb https://download.docker.com/linux/ubuntu {{ ansible_distribution_release | lower }} stable
state: present
- name: Install Docker Engine
apt:
state: latest
name: ['docker-ce', 'docker-ce-cli']
- name: Install Docker Modules for Python
pip:
name: ['docker', 'docker-compose']
Mon rôle étant créé, je n’ai plus qu'à l’ajouter à la liste de rôles dans mon playbook :
roles:
- {role: docker, tags: ['system', 'docker']}
Je peux maintenant exécuter mon rôle Docker via la commande suivante (et aller me prendre une petite 🍺 selon l’heure) :
ansible-playbook -i inventory playbook.yml --tags docker
Maintenant que j’ai Docker d’installé sur mon serveur, il ne me reste plus qu'à déployer un conteneur pour MeiliSearch. Pour cela, je vais utiliser le module Docker d’Ansible et créer le tasks/docker/meilisearch.yml
de ma tâche Ansible :
- file: path=/var/apps/meilisearch state=directory
- name: Create MeiliSearch container
docker_container:
name: meilisearch
state: started
restart: yes
image: getmeili/meilisearch
ports:
- 7700:7700
volumes:
- /var/apps/meilisearch/data.ms:/data.ms
env:
MEILI_ENV: production
MEILI_MASTER_KEY: "{{ lookup('passwordstore', 'servers/wearemd/meilisearch-master-key') }}"
🔒 Prochainement, je vais devoir rendre disponible publiquement l’index de recherche de MeiliSearch en utilisant son API REST. J’ai donc besoin de limiter ce que l’on peut faire via cette API. Du coup, petite variable d’environnement MEILI_MASTER_KEY
qui va bien.
🔑 Et comme il n’y a que moi qui gère les serveurs par chez nous, je gère mes mots de passe, mes tokens et autres trucs secrets avec pass. Ça s’utilise en CLI ou via une extension Firefox ou une GUI ou encore via un plugin Ansible, comme je l’ai fait plus haut :
lookup('passwordstore', 'servers/wearemd/meilisearch-master-key')
Le premier paramètre de la fonction (lookup
) est le nom du plugin (passwordstore
) pour accéder à pass et le second est le chemin de mon secret dans pass (servers/wearemd/meilisearch-master-key
).
Maintenant je fourre ma tâche docker
dans mon playbook :
tasks:
tags: ['docker']
Et enfin, je crée mon conteneur avec la commande qui va bien :
ansible-playbook -i inventory playbook.yml --tags docker --skip-tags system
Et paf on a l’interface web de MeiliSearch disponible ici ! Pour le moment l’index de recherche est vide donc on ne peut pas tester plus loin, mais tout fonctionne comme attendu.
Je maronne souvent sur le temps que met Ansible à faire son boulot. J’utilise beaucoup les tags afin de circonscrire l’exécution de mon playbook à une seule partie. Comme j’avais plein de notes sur le sujet et que je n’avais encore rien creusé, c'était un peu l’occasion ou jamais de voir comment accélérer l’exécution de mon playbook.
En résumé :
David Authier
Développeur freelance