Journaux liées à cette note :

Enlever des couches : mon chemin de Make vers de simples scripts Bash #Doctrine, #dev-kit, #software-engineering, #mise

J'estime le temps de lecture de cette note à 10 minutes

Je profite d'une discussion entre deux amis au sujet de just et make pour partager mon point de vue et mes pratiques sur ce sujet.

Je tiens tout de suite à préciser que c'est un sujet qui me tient à cœur, parce qu'il m'irrite fortement : j'ai lutté pendant des années avec la mauvaise Developer eXperience de l'outil make dans mes projets, et je continue à voir tant de développeurs s'entêter à utiliser un outil dont la raison d'être est la résolution de dépendances basée sur les timestamps de fichiers — or, il me semble que cette fonctionnalité n'est probablement jamais utilisée, sauf dans les projets C ou C++.

Tout d'abord, je souhaite commencer par lister quelques éléments de complexité des makefile.

Quelques exemples de complexité accidentelle apportée par Make

  • Chaque ligne est un sous-shell indépendant et ça c'est super pénible, exemple :
# Le "cd" n'a aucun effet sur la ligne suivante
broken-cd:
	cd /tmp
	ls    # ← liste le répertoire original, pas /tmp

Une solution de contournement est d'utiliser des backslashes pour continuer la ligne, mais cela complique la lisibilité :

build:
    cd /tmp && \
    ls && \
    echo "done"
  • Par défaut, Make utilise sh et non pas bash ou zsh et ne supporte pas la construction [[ ]], les tableaux, etc qui cassent silencieusement. Exemple de code qui ne fonctionne pas :
check-env:
	@if [[ -z "$(ENV)" ]]; then \
		echo "ENV is not set"; \
		exit 1; \
	fi
	@echo "ENV = $(ENV)"
  • L'indentation du contenu des rules doit être une tabulation (pas des espaces)
  • Les $ doivent être doublés pour le shell, sinon make l'interprète, exemple :
greet:
	@MSG="Hello $(APP_NAME)" && \    # $(APP_NAME) → résolu par make ✓
	echo $$MSG                        # $$MSG → variable bash du sous-shell ✓
	@echo $(MSG)                      # $(MSG) → make cherche "MSG" → vide ! ✗

# Piège 3 : le $ doit être doublé pour bash, sinon make l'interprète
list:
	@for i in 1 2 3; do echo $$i; done   # ✓ correct
	@for i in 1 2 3; do echo $i; done    # ✗ make interprète $i → vide
  • Le préfixe "-" permet d'ignorer les erreurs d'une commande est une convention propre à makefile, sans équivalent dans Bash
clean:
	-rm -rf build/    # sans "-", make s'arrête si build/ n'existe pas
	-docker rmi $(APP_NAME)
  • Par défaut, make affiche chaque commande avant de l'exécuter. Pour le supprimer, il faut préfixer chaque ligne avec @ :
build:
    echo "Building..."      # affiche : echo "Building..." puis : Building...
    @echo "Building..."     # affiche seulement : Building...

Du coup, dans la pratique, on se retrouve à préfixer toutes les lignes avec @ :

deploy:
    @echo "Deploying..."
    @docker build -t myapp .
    @kubectl apply -f k8s/
  • Nécessité d'ajouter des .PHONY

Pourquoi tant de difficulté pour lancer de simples commandes ?

À chaque fois que je rencontrais des problèmes avec make, je culpabilisais. Je me disais que c'était de ma faute, que tout le monde utilisait make et qu'il devait y avoir une bonne raison. Je voyais bien que mon expérience de développeur (DX) était mauvaise, que je n'avais pas besoin de résolution de dépendance… mais je me disais que je devais utiliser make, et que mon erreur était de ne pas avoir pris le temps de lire sa documentation.
Alors je replongeais régulièrement dans les 16 chapitres de la documentation de make et je me demandais pourquoi je devais apprendre la syntaxe de make en plus de celle de bash. Et au final, je finissais même par détester Bash en plus de make.

Pourquoi tout cela était-il aussi compliqué, alors que je voulais seulement lancer de simples commandes et intégrer quelques conditions dans mes scripts ?

La recherche d'alternative

En 2018, la douleur des makefiles revenait souvent dans nos discussions en interne, au sein de mon équipe, et on cherchait régulièrement des alternatives. Parmi les pistes étudiées :

  • Task, en Golang, apparu en 2017 — je l'ai testé et ai fortement envisagé de l'adopter
  • Pydoit, en Python, démarré en 2008
  • Rake, en Ruby, lancé en 2003 — alors que je ne maîtrise pas le Ruby et que, par goût personnel, j'évite au maximum d'intégrer ce type de projet dans mes stacks
  • CMake, qu'un collègue avait exploré

Fin 2018, la prise de conscience

Fin 2018, je ne me souviens plus pour quelle raison, en parcourant le code source de Terraform, je suis tombé sur le dossier scripts/) de Terraform.

├── ...
├── Makefile
├── ...
├── scripts
│   ├── build.sh
│   ├── changelog-links.sh
│   ├── changelog.sh
│   ├── copyright.sh
│   ├── debug-terraform
│   ├── exhaustive.sh
│   ├── gofmtcheck.sh
│   ├── gogetcookie.sh
│   ├── goimportscheck.sh
│   ├── staticcheck.sh
│   ├── syncdeps.sh
│   └── version-bump.sh
└── ...

Et un fichier makefile minimaliste qui lance simplement des fichiers Bash :

$ cat Makefile
protobuf:
        go run ./tools/protobuf-compile .

fmtcheck:
        "$(CURDIR)/scripts/gofmtcheck.sh"

importscheck:
        "$(CURDIR)/scripts/goimportscheck.sh"

staticcheck:
        "$(CURDIR)/scripts/staticcheck.sh"

exhaustive:
        "$(CURDIR)/scripts/exhaustive.sh"

[...snip...]

Et, ce jour-là, je me suis senti très stupide d'avoir passé tant de temps à trouver une solution qui était en réalité très simple, à portée de main !

Je pense aussi que le fait que cette méthode ait été utilisée par Mitchell Hashimoto en personne, dans Terraform, m'a probablement donné une sorte d'autorisation d'utiliser cette approche.

J'ai compris que je pouvais simplement me passer de make.

2019 à 2026 : utilisation de simples scripts Bash

Suite à ma prise de conscience de fin 2018, j'ai appliqué un principe que je nomme "enlever des couches" : plutôt que d'ajouter une technologie pour résoudre un problème, réfléchir à ce que peut enlever pour réduire la complexité — et, par la même, peut-être supprimer le problème lui-même. C'est une vigilance consciente contre le biais cognitif du cargo cult : la tendance à reproduire des pratiques par habitude ou imitation, sans vraiment les comprendre ni les justifier.

En appliquant ce principe, il m'a semblé que je pouvais simplement enlever make — sans avoir à le remplacer par un outil tel que Task qui aurait été une couche supplémentaire dont je n'avais probablement pas besoin.

J'ai même pris conscience qu'en plaçant tous mes scripts dans un dossier ./scripts/, je bénéficiais nativement de l'autocomplétion de mes commandes par le filesystem — tout comme ce que proposait aussi make.

Par exemple :

  • make up devenait ./scripts/up.sh
  • make build devenait ./scripts/build.sh
  • make clean devenait ./scripts/clean.sh
  • etc.

Et surtout, je pouvais désormais pleinement me concentrer sur ma maîtrise de Bash pour améliorer l'expérience de développeur (DX) de mes kits de développement.

L'astuce du cd automatique

Pour exécuter ces commandes sans se préoccuper du dossier courant, j'ai ajouté la ligne suivante au début de chaque script :

cd "$(dirname "$0")/../"

Cela permet de lancer ./scripts/up.sh depuis la racine du projet comme depuis un sous-répertoire (cd subproject && ../scripts/up.sh), et le script s'exécutera toujours depuis le dossier parent de scripts.

Voici le boilerplate code qu'utilise la quasi-totalité de mes scripts :

#!/usr/bin/env bash
set -e

cd "$(dirname "$0")/../"

...

Mais "make" est un standard ?

L'argument revient souvent : « make est un standard, tout le monde le connaît, un nouveau contributeur saura immédiatement quoi faire. ».

Seulement voilà : la partie « standard » de make, celle que tout le monde utilise réellement, c'est make <target> — et c'est exactement ce que fait ./scripts/<target>.sh, sans syntaxe supplémentaire, sans pièges de tabulations, sans résolution de dépendances par timestamps dont on ne veut probablement pas.

Il me semble que cet argument touche au cargo cult : on place un Makefile à la racine du projet par habitude, sans vraiment tirer parti des capacités qui justifient l'existence même de make.

De plus, si l'on parle de standard, bash est probablement au moins aussi universel que make. Et écrire un script bash est sans doute plus accessible pour un développeur que d'apprendre les subtilités du makefile ($ doublés, sous-shells, .PHONY, @, -, etc.).

Il me semble donc que l'argument du "standard" est légitime — mais mon choix de ne plus utiliser make n'est pas un obstacle pour autant : si ./scripts/up.sh est clairement documenté dans le README, je pense que n'importe quel développeur comprendra sans difficulté son usage et sa fonction. Pas besoin de connaître make pour exécuter un script bash dont le nom est explicite.

Retour d'expérience : 4 ans, de 2 à 10 développeurs

J'ai utilisé cette méthode avec succès pendant 4 ans, en passant de 2 à 10 développeurs, sans que j'aie constaté de friction. À ma connaissance, personne n'a eu de difficulté avec ce système d'exécution des scripts et, il me semble, personne ne m'a suggéré de les remplacer par autre chose.

Et Just, alors ?

J'ai découvert just en 2022, puis je l'ai vu gagner en popularité à partir de 2023 (199 commentaires sur HackerNews) :

J'ai failli me laisser tenter. Mais je n'avais aucune douleur avec mes scripts, j'étais pleinement satisfait — et conformément au principe d'enlever des couches, ajouter une couche supplémentaire n'avait aucun intérêt.

D'autre part, just est riche en fonctionnalités et sa documentation est déjà importante : il me semble que c'est beaucoup à apprendre pour un outil dont je n'ai pas besoin.

Et puis j'ai craqué pour Mise Tasks

Je suis un grand utilisateur de Mise et dernièrement ce projet a ajouté la fonctionnalité Tasks. Et au grand désespoir de mon ami Alexandre — qui me fait régulièrement remarquer cette contradiction —, j'ai craqué, j'ai commencé à utiliser cette fonctionnalité en janvier 2026. Je n'ai pas d'argument solide à avancer ; sans doute un mélange de curiosité et d'affection pour Mise.

Contrairement à just, la fonctionnalité task de Mise reste minimaliste et est compatible avec mon paradigme : le if dans l'exemple ci-dessous est du Bash standard — pas besoin de $$, de \, de sous-shells par ligne. J'écris du Bash et rien d'autre.

D'autre part, Mise est déjà au cœur de mes development kit, je l'utilise à depuis 2023 à la place de Asdf pour installer du tooling de développement. Depuis 1 an, j'ai remplacé direnv par Mise. Par conséquent, ce n'est pas une dépendance en plus à ajouter à mes projets.

Mise task supporte trois syntaxes pour définir des tasks.

Dans le fichier .mise.toml, en ligne simple :

[tasks.build]
run = "pnpm run build"

Ou en bloc multiligne :

[tasks.clean]
run = """
if [ "$1" = "--with-lint" ]; then
  mise run lint
fi
pnpm run test
"""

Ou alors, via des scripts dans le dossier mise-tasks/, par exemple mise-tasks/build :

#!/usr/bin/env bash
#MISE description="Build the web application"
pnpm run build

Voici un extrait de Mise tasks mises en œuvre dans un vrai projet :

$ mise task
Name                           Description
build-cli                      Build the sklein-devbox CLI application
build-image                    Build the sklein-devbox container image
[...snip...]
up                             Start the devbox container

Le code source est consultable ici : https://github.com/stephane-klein/sklein-devbox/blob/main/.mise.toml

C'est important pour moi de préciser que j'ai bien conscience que Mise Tasks est une couche de plus — et que ça contredit ma doctrine « enlever des couches ».
Dans un projet d'équipe, je partirais par défaut sur des scripts Bash simples, sans Mise task. Je n'intégrerais Mise task que s'il y a un consensus fort de l'équipe — et je ne l'imposerais pas.

Remerciements

Je remercie mes deux amis de m'avoir motivé à écrire cette note — c'est un sujet que je souhaitais traiter depuis 2019 (j'avais même créé une issue à ce sujet dans mon ancien backlog).

Journal du dimanche 16 novembre 2025 à 22:17 #projet-34, #vpn, #admin-sys

Suite à publication des notes "Setup Fedora CoreOS avec LUKS et TPM, non sécurisé contre le vol physique de serveur", "Setup Fedora CoreOS avec LUKS et Tang", j'ai réfléchi à mes prochaines itérations du Projet 34 - "Déployer un cluster k3s et Kubevirt sous CoreOS dans mon Homelab".

Je souhaite réaliser et publier un playground pour étudier et tester les solutions VPN suivantes :

Dans un premier temps, je souhaite pouvoir accéder en ssh aux serveurs de mon Homelab depuis n'importe où. L'objectif est d'utiliser une méthode unique pour me connecter à ces serveurs en utilisant simplement leur hostname, sans avoir à gérer leurs adresses IP locales ni à configurer manuellement des entrées DNS.

Je souhaite tester l'installation de ces solutions sur des serveurs sous CoreOS, ma workstation sous Fedora et sous Android.

Idéalement, je souhaite configurer les services netbird et Tailscale via Terraform.

Je ne pense pas tester tout le suite headscale.

Journal du jeudi 06 novembre 2025 à 10:28 #Microsoft, #DevOps, #InfrastructureAsCode, #JaiDécouvert

Dans mon activité professionnelle, #JaiDécouvert Bicep (https://github.com/Azure/bicep) équivalent pour Microsoft Azure de Terraform et CloudFormation.


Je découvre aussi le format ARM Template JSON :

Bicep code is transpiled to standard ARM Template JSON files, which effectively treats the ARM Template as an Intermediate Language (IL).

source

Dans ce contexte, j'apprends qu'ARM signifie Azure Resource Manager.

Je comprends que le suffixe "rm" dans le nom du provider Terraform d'Azure terraform-provider-azurerm fait référence à "Resource Manager".

Journal du mardi 22 avril 2025 à 17:57 #JaiDécouvert, #DevOps, #terraform, #JaimeraisUnJour

J'ai un collègue qui utilise Terragrunt (https://terragrunt.gruntwork.io/).
Je pense que j'ai déjà croisé cet outil mais sans trop y prêter attention.

Pour le moment, je ne comprends pas très bien l'intérêt de Terragrunt, j'ai l'impression que c'est un wrapper au-dessus de Terraform ou OpenTofu.

#JaimeraisUnJour prendre le temps de faire un POC de Terragrunt.

Journal du vendredi 07 février 2025 à 16:12 #DevOps

Exemples d'outils qui suivent de modèle Orchestration Push Mode :

Exemples d'outils qui suivent le modèle Orchestration Pull Mode :

Journal du dimanche 19 janvier 2025 à 11:24 #proxmox, #homelab, #network, #nftables, #iteration, #DevOps, #Server

#iteration Projet GH-271 - Installer Proxmox sur mon serveur NUC Intel i3-5010U, 8Go de Ram :

Être capable d'exposer sur Internet un port d'une VM.

source

Voici comment j'ai atteint cet objectif.

Pour faire ce test, j'ai installé un serveur http nginx sur une VM qui a l'IP 192.168.1.236.

Cette IP est attribuée par le DHCP installé sur mon routeur OpenWrt. Le serveur hôte Proxmox est configuré en mode bridge.

Ma Box Internet Bouygues sur 192.168.1.254 peut accéder directement à cette VM 192.168.1.236.

Pour exposer le serveur Proxmox sur Internet, j'ai configuré mon serveur Serveur NUC i3 gen 5 en tant que DMZ host.

J'ai suivi la recommandation pour éviter une attaque du type : DNS amplification attacks

DNS amplification attacks involves an attacker sending a DNS name lookup request to one or more public DNS servers, spoofing the source IP address of the targeted victim.

source

Avec cette configuration, je peux accéder en ssh au Serveur NUC i3 gen 5 depuis Internet.

J'ai tout de suite décidé d'augmenter la sécurité du serveur ssh :

# cat <<'EOF' > /etc/ssh/sshd_config.d/sklein.conf
Protocol 2
PasswordAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
KbdInteractiveAuthentication no
X11Forwarding no
# systemctl restart ssh

J'ai ensuite configuré le firewall basé sur nftables pour mettre en place quelques règles de sécurité et mettre en place de redirection de port du serveur hôte Proxmox vers le port 80 de la VM 192.168.1.236.

nftables est installé par défaut sur Proxmox mais n'est pas activé. Je commence par activer nftables :

root@nuci3:~# systemctl enable nftables
root@nuci3:~# systemctl start nftables

Voici ma configuration /etc/nftables.conf, je me suis fortement inspiré des exemples présents dans ArchWiki : https://wiki.archlinux.org/title/Nftables#Server

# cat <<'EOF' > /etc/nftables.conf
flush ruleset;

table inet filter {
    # Configuration from https://wiki.archlinux.org/title/Nftables#Server
    set LANv4 {
        type ipv4_addr
        flags interval

        elements = { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 }
    }
    set LANv6 {
        type ipv6_addr
        flags interval

        elements = { fd00::/8, fe80::/10 }
    }

    chain input {
        type filter hook input priority filter; policy drop;
        iif lo accept comment "Accept any localhost traffic"

        ct state invalid drop comment "Drop invalid connections"
        ct state established,related accept comment "Accept traffic originated from us"

        meta l4proto ipv6-icmp accept comment "Accept ICMPv6"
        meta l4proto icmp accept comment "Accept ICMP"
        ip protocol igmp accept comment "Accept IGMP"

        udp dport mdns ip6 daddr ff02::fb accept comment "Accept mDNS"
        udp dport mdns ip daddr 224.0.0.251 accept comment "Accept mDNS"

        ip saddr @LANv4 accept comment "Connections from private IP address ranges"
        ip6 saddr @LANv6 accept comment "Connections from private IP address ranges"

        tcp dport ssh accept comment "Accept SSH on port 22"
        tcp dport 8006 accept comment "Accept Proxmox web console"

        udp sport bootpc udp dport bootps ip saddr 0.0.0.0 ip daddr 255.255.255.255 accept comment "Accept DHCPDISCOVER (for DHCP-Proxy)"
    }

    chain forward {
        type filter hook forward priority filter; policy accept;
    }

    chain output {
        type filter hook output priority filter; policy accept;
    }
}

table nat {
    chain prerouting {
        type nat hook prerouting priority dstnat;
        tcp dport 80 dnat to 192.168.1.236;
    }
    chain postrouting {
        type nat hook postrouting priority srcnat;
        masquerade
    }
}
EOF

Pour appliquer en toute sécurité cette configuration, j'ai suivi la méthode indiquée dans : "Appliquer une configuration nftables avec un rollback automatique de sécurité".

Après cela, voici les tests que j'ai effectués :

  • Depuis mon réseau local :
    • Test d'accès au serveur Proxmox via ssh : ssh root@192.168.1.43
    • Test d'accès au serveur Proxmox via la console web : https://192.168.1.43:8006
    • Test d'accès au service http dans la VM : curl -I http://192.168.1.236
  • Depuis Internet :
    • Test d'accès au serveur Proxmox via ssh : ssh root@176.142.86.141
    • Test que je n'ai pas accès au serveur Proxmox via la console web : curl http://176.142.86.141:8006
    • Test d'accès au service http dans la VM : curl -I http://176.142.86.141

Voilà, tout fonctionne correctement 🙂.

Prochaines étapes :

  • Être capable d'accéder depuis Internet via IPv6 à une VM
  • Je souhaite arrive à effectuer un déploiement d'une Virtual instance via Terraform

Journal du lundi 23 décembre 2024 à 19:39 #selfhosting, #proxmox, #DevOps, #bug, #iteration

J'ai commencé le Projet GH-271 - Installer Proxmox sur mon serveur NUC Intel i3-5010U, 8Go de Ram le 9 octobre.
Le 27 octobre, j'ai publié la note 2024-10-27_2109 qui contient une erreur qui m'a fait perdre 14h !

La ligne en question :

# virt-customize -a noble-server-cloudimg-amd64.img --install qemu-guest-agent --run-command 'systemctl enable qemu-guest-agent.service'
[   0.0] Examining the guest ...
[   4.5] Setting a random seed
virt-customize: warning: random seed could not be set for this type of
guest
[   4.5] Setting the machine ID in /etc/machine-id
[   4.5] Installing packages: qemu-guest-agent

[  32.1] Running: systemctl enable qemu-guest-agent.service
[  32.6] Finishing off

Je n'avais pas fait attention au message Setting the machine ID in /etc/machine-id 🙊.

Conséquence : le template Proxmox Ubuntu contenait un fichier /etc/machine-id avec un id.
Conséquence : toutes les Virtual machine que je créais sous Proxmox avaient la même valeur machine-id.

J'ai découvert que l'option 61 "Client identifier" du protocole DHCP permet de passer un client id au serveur DHCP qui sera utilisé à la place de l'adresse MAC.

Conséquence : le serveur DHCP assignait la même IP à ces Virtual machine.

J'ai pensé que le serveur DHCP de mon router BBox avait un problème. J'ai donc décidé d'installer Projet 15 - Installation et configuration de OpenWrt sur Xiaomi Mi Router 4A Gigabit pour avoir une meilleure maitrise du serveur DHCP.

Problème : j'ai fait face au même problème avec le serveur DHCP de OpenWrt.

Après quelques recherches, j'ai découvert que contrairement à virt-customize la commande virt-sysprep permet d'agir sur des images qui ont vocation à être clonées.

"Sysprep" stands for "system preparation" tool. The name comes from the Microsoft program sysprep.exe which is used to unconfigure Windows machines in preparation for cloning them.

source

Pour corriger le problème, j'ai remplacé cette ligne :

# virt-customize -a noble-server-cloudimg-amd64.img --install qemu-guest-agent --run-command 'systemctl enable qemu-guest-agent.service'

Par ces deux lignes :

# virt-sysprep -a noble-server-cloudimg-amd64.img --network --install qemu-guest-agent --run-command 'systemctl enable qemu-guest-agent.service'
# virt-sysprep --operation machine-id -a noble-server-cloudimg-amd64.img

La seconde commande permet de supprimer le fichier /etc/machine-id, ce qui corrige le problème d'attribution d'IP par le serveur DHCP.

À noter que je ne comprends pas pourquoi il est nécessaire de lancer explicitement cette seconde commande, étant donné que la commande virt-sysprep est destinée aux images de type "template". Le fichier /etc/machine-id ne devrait jamais être créé, ou tout du moins, automatiquement supprimé à la fin de chaque utilisation de virt-sysprep.

Maintenant, l'instanciation de Virtual machine fonctionne bien, elles ont des IP différentes 🙂.

Prochaine étape du Projet GH-271 :

Je souhaite arrive à effectuer un déploiement d'une Virtual instance via cli de Terraform.

Le support des variables d'environments de Mise est limité, je continue à utiliser direnv #direnv, #dev-kit

J'ai décidé d'utiliser la fonctionnalité "mise env._source" pendant quelques semaines pour me faire une opinion.

-- (from)

J'ai déjà rencontré un problème : il n'est pas possible de lancer des outils installés via Mise dans un script lancé par _.source.

Voici un exemple, j'ai ce fichier .envrc.sh :

export SERVER1_IP=$(terraform output --json | jq -r '.server1_public_ip | .value')

Terraform est installé avec Mise :

[env]
_.source = "./.envrc.sh"

[tools]
terraform="1.9.8"

Quand je lance mise set, j'ai cette erreur :

$ mise set
.envrc.sh: line 6: terraform: command not found

J'ai trouvé une issue pour traiter cette limitation : "Use mise tools in env template".

En attendant que cette issue soit implémentée, j'ai décidé de continuer d'utiliser direnv.


2024-12-19 : suite à la cloture de l'issue indiquée dans cette note, j'ai publié la note Je pense maintenant pouvoir remplacer Direnv par Mise 🤞.

AWS RDS playground et fixe du problème pg_dumpall #DevOps, #admin-sys, #AWS, #playground

En 2019, j'ai rencontré un problème lors de l'exécution de pg_dumpall sur une base de données PostgreSQL hébergée sur AWS RDS. À l'époque, ce problème était "la goutte d'eau" qui m'avait empressé de migrer de RDS vers une instance PostgreSQL self hosted avec une simple image Docker dans un docker-compose.yml, mais je digresse, ce n'est pas le sujet de cette note.

Aujourd'hui, j'ai fait face à nouveau à ce problème, mais cette fois, j'ai décidé de prendre le temps pour bien comprendre le problème et d'essayer de le traiter.

Pour cela, j'ai implémenté et publié un playground nommé rds-playground.

Je peux le dire maintenant, j'ai trouvé une solution à mon problème 🙂.

Ce playground contient :

  • Un exemple de déploiement d'une base de données AWS RDS avec Terraform.
  • Un script qui permet d'importer avec succès la base de données AWS RDS vers une instance locale de PostgreSQL, en incluant les rôles.

Au départ, je pensais que le problème venait d'un problème de configuration des rôles du côté de AWS RDS ou alors que je n'utilisais pas le bon user. J'ai ensuite compris que c'était une fausse piste.

J'ai ensuite découvert ce billet : "Using pg_dumpall with AWS RDS Postgres".

For those interested, RDS Postgres (by design) doesn't allow you to read pg_authid, which was earlier necessary for pg_dumpall to work.

J'ai compris que pour exécuter un pg_dumpall sur une instance RDS, il est impératif d'utiliser l'option --no-role-passwords.

Autre subtilité : sur une instance RDS, le rôle SUPERUSER est attribué au rôle rlsadmin, tandis que cette option est supprimé du rôle postgres.

ALTER ROLE postgres WITH NOSUPERUSER INHERIT CREATEROLE
CREATEDB LOGIN NOREPLICATION NOBYPASSRLS VALID UNTIL 'infinity';

Par conséquent, j'ai décidé d'utiliser le même nom d'utilisateur superuser pour l'instance locale PostgreSQL :

services:
  postgres:
    image: postgres:13.15
    environment:
      POSTGRES_USER: rdsadmin
      POSTGRES_DB: postgres
      POSTGRES_PASSWORD: password
      ...

Pour aller plus loin, je vous invite à suivre le README.md de rds-playground.

Journal du dimanche 13 octobre 2024 à 19:27 #OnMaPartagé

Alexandre m'a partagé le projet terraform-provider-ansible qui permet de lancer des playbook Ansible depuis Terraform.

Test