# 2023/06/19 (atelier) : Ansible * [Réunion précédente](https://doc.neutrinet.be/atelier-ansible-2023-05-18) * [Pad de la réunion](https://doc.neutrinet.be/atelier-ansible-2023-06-19#) Présences : - HgO - Célo ## 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: ```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`). ```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 : ```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. ```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: ```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 :scream_cat: 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.// {{tag>infra atelier}}