Table des matières
2023/06/19 (atelier) : Ansible
Météo
Moment informel durant lequel on exprime en peu de mots comment on se sent et si on a une attente forte pour la réunion. Ce n'est pas un moment de discussion mais d'expression individuelle et ce n'est pas obligatoire
Attente(s) forte(s)
Si l'une ou l'autre personne exprime une attente forte, merci de vous en occuper en priorité ou de la noter dans le hub ou dans un point approprié.
Fin: 17h30
Anciens TODOs
- Demander à Alyve pour récupérer la gestion des DNS (elle est sur Matrix et Mastodon) → demande du transfert du domaine → en cours
- Rajouter la gestion du SMTP dans le playbook → Célo a fait des trucs
- Rajouter la config pour l'IPv6 dans la BDD : https://community.fly.io/t/failed-to-connect-to-database-cluster-non-existing-domain/1223
- Préparation de la migration de Mobilizon, càd copier les données de mobilizon.be et les placer sur la nouvelle VM
- Tester le redémarrage de la VM
Configuration
GeoCoder
Sur mobilizon.be, on utilise Nominatim comme geocoder, à voir dans la doc s'il faut installer des trucs: https://docs.joinmobilizon.org/administration/configure/geocoders/
D'autres Géocoders sont possibles mais c'est vite assez cher.
Pour le moment on garde Nominatim, et on verra plus tard s'il faut changer. Il faudra regarder combien de requêtes par mois sont faites vers Nominatim.
SMTP
Il reste encore à configurer Mobilizon pour envoyer des mails.
On peut regarder comment c'est fait sur mobilizon.be
Sur le serveur, cela se trouve dans le dossier live/config/runtime.exs
. Il y a une partie pour le SMTP:
config :mobilizon, Mobilizon.Web.Email.Mailer,
On réutilise la config SMTP, mais on la changera sans doute plus tard quand on aura les accès au nom de domaine (création d'une boîte mail chez Neutrinet ?)
Postgis
Il faut qu'on installe le plugin postgresql-13-postgis
sur tous les hosts postgresql, car sinon la base de données de Mobilizon se casse la figure lorsqu'un autre serveur devient le serveur primaire.
On doit faire une boucle dans le rôle ansible, car la directive delegated_to
ne permet pas d'indiquer plusieurs hosts.
On peut utiliser la variable postgresql_patroni_hosts
qui contient la liste des serveurs du cluster patroni.
On utilise la directive loop
pour parcourir la liste des serveurs postgresql définis dans la variable postgresql_patroni_hosts
, et pour chaque serveur dans la liste on délègue la tâche vers celui-ci:
- snippet.yaml
delegate_to: "{{ postgresql_host }}" loop: "{{ postgresql_patroni_hosts }}" loop_control: loop_var: postgresql_host
Le problème, c'est qu'il y a deux cas différents. Lorsque le playbook est exécuté sur une machine qui fait partie d'un cluster patroni, la liste définie dans la variable postgresql_patroni_hosts
n'est pas vide et la tâche se déroule bien. Cependant, lorsque le rôle est lancé localement avec molécule, la tâche n'est pas effectuée car la liste des hosts patroni est vide.
Une première possibilité est d'écrire deux fois la tâche. Une première fois pour le cas où le playbook est lancé sur une machine qui fait partie d'un cluster (on ne lance alors la tâche que lorsque la variable contient plus d'éléments que 0 en utilisant l'opérateur when
).
- snippet.yaml
- name: Installation de la dépendance postgresql pour postgis ansible.builtin.package: name: - postgresql-{{ postgresql_major_version }}-postgis state: present delegate_to: "{{ postgresql_host }}" loop: "{{ postgresql_patroni_hosts }}" loop_control: loop_var: postgresql_host when: postgresql_patroni_hosts | length > 0
Puis une seconde fois pour le cas où la liste est vide et où la tâche n'a pas été appliquée, en spécifiant de ne faire cette opération que lorsque la liste est vide :
- snippet.yaml
- name: Installation de la dépendance postgresql pour postgis ansible.builtin.package: name: - postgresql-{{ postgresql_major_version }}-postgis state: present delegate_to: "{{ inventory_hostname }}" when: postgresql_patroni_hosts | length == 0
(On note l'opérateur when
qui change, dans un cas avec length > 0
et une boucle, et dans l'autre avec length == 0
sans boucle)
L'avantage de cette méthode : cela rend le code lisible. L'inconvénient, c'est que ce n'est pas très optimisé et c'est très verbeux.
- snippet.yaml
- name: Installation de la dépendance postgresql pour postgis ansible.builtin.package: name: - postgresql-{{ postgresql_major_version }}-postgis state: present delegate_to: "{{ postgresql_host }}" loop: "{{ postgresql_patroni_hosts if (postgresql_patroni_hosts | length > 0) else [inventory_hostname] }}" loop_control: loop_var: postgresql_host
Dans la directive loop
, on dit : « Prend la liste définie dans la variable postgresql_patroni_hosts
, uniquement si la liste contient des éléments. Sinon, prend la liste qui contient l'élément inventory_hostname
». On doit en effet définir dans les deux cas une liste pour que la boucle fonctionne.
Dans ce genre de situation, soit on privilégie la lisibilité, soit on rajoute plein de commentaire pour ne pas oublier dans 3 mois.
En général, on utilise plutôt les if
/ else
dans des templates, et on évite de les utiliser dans les tâches. Donc on va partir sur la solution plus verbeuse.
Connexion base de données en IPv6
On doit rajouter l'option socket_options
dans la config de Mobilizon pour que la connexion puisse se faire en IPv6:
- snippet.ruby
config :mobilizon, Mobilizon.Storage.Repo, adapter: Ecto.Adapters.Postgres, socket_options: [:inet6],
SSH agent
On configure le SSH agent pour qu'il arrête de nous embêter avec les clés SSH et les mots de passe dans tous les sens:
https://wiki.archlinux.org/title/SSH_keys#Start_ssh-agent_with_systemd_user
Il faut sans doute créer le dossier pour pouvoir y mettre la config:
mkdir -p ~/.config/systemd/user
On crée la config ssh-agent.service
:
[Unit] Description=SSH key agent [Service] Type=simple Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket ExecStart=/usr/bin/ssh-agent -t 1h -D -a $SSH_AUTH_SOCK [Install] WantedBy=default.target
Avec l'option -t
on peut définir la durée de validité des clés SSH, c'est pratique pour ne pas avoir une dizaine de clés actives à la fin de la journée.
Lorsque la config a été créée, on fait:
systemctl start --user ssh-agent systemctl enable --user ssh-agent
Dans la config ~/.bashrc
ou ~/.zshrc
, on rajoute:
export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"
Enfin, on ouvre un nouveau terminal et on vérifie que le ssh-agent tourne:
ssh-add -l
On rajoute également la commande magique dans ~/.ssh/config
pour que SSH rajoute les clés qu'il utilise directement dans le SSH agent:
AddKeysToAgent yes
Tests du playbook
On a pu lancer le playbook en local via molécule, maintenant on va le lancer sur la VM mobilizon.patata.louise.neutri.net qu'on avait créé le mois passé.
Ensuite, on lance manuellement un backup borgmatic, ceci afin de pouvoir tester la restauration des backups.
On vérifie qu'on a bien sauvegardé la clé Borg qui se trouve dans /root/.config/borg/keys
.
On supprime la base de donnée en se rendant sur le postgresql primaire. Ici, c'est pgsql-03.patata.louise.neutri.net. On fait un beau drop database:
sudo -u postgres dropdb mobilizon-neutrinet-be
Il nous dit que quelqu'un est en train d'utiliser la db, donc on stop Mobilizon et on recommence.
Ensuite, on se connecte au Proxmox pour repartir d'un snapshot de la VM Mobilizon.
Maintenant, on lance le playbook commun pour provisionner à nouveau la VM
Pour faire un restore des backups, voir la doc: https://torsion.org/borgmatic/docs/how-to/extract-a-backup/
~~Par contre, pour le moment on n'a pas encore la config borgmatic de Mobilizon… Il faut donc lancer le playbook pour au moins avoir cette config:~~
ansible-playbook playbooks/apps/mobilizon.yml -t borgmatic_config -l mobilizon --diff
En fait on n'a pas besoin de cette étape
~~Lorsque c'est fait,~~ on peut restaurer les fichiers de Mobilizon:
borgmatic extract -c /etc/borgmatic.d/common.yml --archive latest --destination / --progress
On doit préciser où le backup doit être restaurer (sinon il le fait par défaut à l'endroit où on lance la commande). On peut ajouter le flag --progress
pour que borg indique ce qu'il fait et où il en est.
Il faut encore restaurer la db postgresql, le dump se trouve dans /root/.borgmatic/postgresql_databases
.
Il y a une commande magique de borgmatic pour faire ça, mais malheureusement il faut que le client postgresql soit installé (ou du monis le paquet pg_restore
). On va d'abord le faire manuellement sur pgsql-03, et on testera la commande magique plus tard.
On crée la base de données:
sudo -u postgres createdb mobilizon-neutrinet-be
Ensuite on restaure les données:
sudo -u postgres pg_restore -d mobilizon-neutrinet-be /tmp/mobilizon-neutrinet-be
Et enfin, on vérifie que les données sont bien là:
sudo -u postgres psql mobilizon-neutrinet-be`
On lance le playbook qui rajoute Caddy et le client Posgresql mais ne fait pas grand chose d'autre à part changer le masque sur /var/www
.
Par contre, on remarque qu'on a des problèmes de permissions sur les fichiers de Mobilizon (ex: /var/www/mobilizon-neutrinet-be appartient à root).
En fait, c'est parce que borgmatic restaure les fichiers avant la création de l'utilisateur mobilizon (puisque celui-ci n'a pas encore été créé avec le playbook). Le mieux est donc de lancer d'abord le playbook puis de restaurer les données via borgmatic.
Néanmoins, il semble que même lorsque pg_restore (lié au client postgresql) est installé, la restauration de la DB via borg ne fonctionnent pas. Ce n'est pas grave puisqu'on peut le faire à la main.
Geolix
Il y a un machin, ça s'appelle Geolix mais on sait pas trop à quoi ça sert :
https://hexdocs.pm/geolix/Geolix.html
Au passage, on découvre la doc des CÉMÉA qui a l'air super complète \o/
https://ladoc.cemea.org/mallette/mobilizon
Cela permet de montrer des évènements en se basant sur la localisation de l'IP. En fait, c'est à la fin de la doc de mobilizon : https://docs.joinmobilizon.org/administration/install/release/#geolocation-databases
Donc si l'IP est sur Bruxelles, on verra tous les évènements de Neutrinet en premier.
On doit juste télécharger la base de données: https://download.db-ip.com/free/dbip-city-lite-2023-06.mmdb.gz
Et la décompresser.
Il y a moyen de mettre en place un cronjob pour mettre à jour cette base de données (voir doc des CÉMÉA), mais on le fera plus tard…
TODO: Mettre en place un cronjob avec l'outil geoipupdate (peut se faire à la main dans un premier temps)
Préparation de la migration
On va devoir récupérer un dump de la base de données de mobilizon.be
Il nous faudra aussi les médias (uploads, etc.), qui se trouvent dans /home/mobilizon/live/uploads
.
TODO:
- Tester avec un dump de la db, une copie des uploads, et voir si on peut se connecter.
- Tester l'envoi de mails
- Tester la création d'un évènement avec localisation (geocoder)
Gopass
- Explication du password manager
- Installation et configuration
- Explication du concept de « password store »
- Comment récupérer un mot de passe
- Comment rajouter un nouveau mot de passe
- Comment modifier un mot de passe
- Comment supprimer un mot de passe
- Ajouter et supprimer des personnes
Prochaine réunion
TODO: Mettre en place un cronjob avec l'outil geoipupdate (peut se faire à la main dans un premier temps)
Prochain atelier Ansible: On attend le transfert du nom de domaine
Lieu : Chez Célo
Météo de fin
Moment informel durant lequel on exprime en peu de mots comment, à titre personnel, la réunion a été vécue que ce soit positif ou négatif. Si une ou plusieurs tension est née durant la réunion, il est peut-être nécessaire d'envisager l'une ou l'autre réunion pour y remédier.