Guide du code
Comment le repo est organisé et où trouver chaque chose, expliqué simplement.
Le repo se lit en deux temps, et une fois que tu as ça en tête tout devient simple.
D'un côté, le dossier modules/ contient des briques : chaque brique fait une seule
chose (gérer les clés de chiffrement, monter le réseau, envoyer les alertes…). De l'autre, le
dossier envs/students/ est le plan de montage : il ne fabrique rien lui-même, il se
contente d'assembler les briques en leur passant les bons réglages. La règle à retenir : on ne
crée jamais une ressource directement dans le plan de montage, on appelle une brique.
Donc quand tu veux modifier quelque chose, tu pars presque toujours d'un fichier dans
envs/students/ (le point d'assemblage), qui pointe vers une brique dans modules/. Et
toutes les commandes Terraform se lancent depuis envs/students/, parce que c'est là qu'est
rangé l'état du projet.
Les secrets et le chiffrement
Le cœur de cette partie, c'est une clé de chiffrement gérée par AWS, ce qu'on appelle KMS
(pour Key Management Service, le service de clés d'AWS). Cette clé est créée par la brique
modules/kms (la ressource aws_kms_key), avec une règle d'accès qui sépare bien ceux qui
gèrent la clé de ceux qui s'en servent pour chiffrer.
Par-dessus, on utilise SOPS, un petit outil qui chiffre des fichiers de configuration en
s'appuyant sur cette clé KMS : c'est la brique modules/sops. Et quand on a besoin de ranger
un mot de passe applicatif, on le met dans le coffre à secrets d'AWS (Secrets Manager) via
modules/secret, sans jamais écrire sa valeur en clair. Côté plan de montage, tout ça se règle
dans sops.tf et secret.tf.
Le réseau
La brique modules/network construit un réseau privé isolé, un VPC (Virtual Private
Cloud, ton bout de réseau à toi chez AWS), avec deux zones : une publique, joignable depuis
internet, et une privée qui ne l'est pas. La brique modules/security-groups pose les
pare-feux (les security groups) qui n'ouvrent que les ports strictement nécessaires.
La machine elle-même, c'est modules/ec2 (la ressource aws_instance) : une instance durcie
où on a forcé IMDSv2, la version 2 du petit service interne qui donne ses informations à la
machine. C'est cette version 2 qui bloque le vol d'identifiants via une faille SSRF, parce
qu'elle exige un échange en deux temps qu'une attaque basique ne sait pas faire. Tout ça se
branche dans network.tf.
Les journaux et les alertes
CloudTrail, le service qui enregistre toutes les actions faites sur le compte AWS, est
posé par modules/cloudtrail : il écrit à la fois dans un stockage S3 et dans
CloudWatch (le service de surveillance d'AWS). Les flux réseau, eux, sont tracés par
modules/logging.
Et surtout, modules/alerting surveille les comportements louches (une connexion avec le
compte root, des actions refusées en série, une modification de droits, une tentative de couper
les journaux…) et t'envoie un mail dès que l'un d'eux se produit, grâce à SNS (le service de
notifications d'AWS). Tu retrouves ces deux parties dans cloudtrail.tf et alerting.tf.
Les droits (IAM)
IAM (Identity and Access Management, la gestion des utilisateurs et de leurs droits chez
AWS) vit dans modules/iam. L'idée tient en deux mots : chaque identité n'a que le strict
nécessaire, et on pose au-dessus une permission boundary, c'est-à-dire un plafond de droits
qu'on ne peut jamais dépasser même en s'attachant d'autres autorisations. C'est précisément ce
qui empêche quelqu'un de se fabriquer un compte admin. Réglages dans iam.tf.
Le pipeline et l'état du projet
Pour que GitHub puisse déployer sans qu'on stocke la moindre clé AWS quelque part, on passe par
OIDC : un mécanisme où GitHub prouve son identité à AWS et reçoit en échange un accès
temporaire, limité à ce dépôt précis. C'est la brique modules/github-oidc, branchée dans
ci.tf.
Quant à l'état du projet (le fichier où Terraform note tout ce qu'il a créé), il n'est pas
laissé sur ton disque : il est rangé dans un stockage S3 chiffré et verrouillé, monté par la
brique modules/tf-backend (backend.tf).
Lancer le projet
cd envs/students
AWS_PROFILE=wany terraform init # prépare les providers et l'état distant
AWS_PROFILE=wany terraform plan # montre ce qui va changer
AWS_PROFILE=wany terraform apply # appliqueLe profil AWS utilisé est wany, la région est eu-west-3, et l'état est distant : il n'y a
donc pas de fichier d'état à committer.
Les règles de l'équipe
Quelques principes simples, à respecter pour ne rien casser :
On fait tout en code. On ne modifie jamais une ressource à la main dans la console AWS,
parce que ça crée un écart entre la réalité et le code, et que le prochain terraform apply
écrasera ton clic. La console sert à regarder, pas à modifier.
Quand on veut déplacer ou renommer des ressources (par exemple sortir du code dans une
nouvelle brique), on utilise des blocs moved : le plan doit alors afficher 0 to destroy,
preuve qu'on réorganise sans rien détruire. Pour reprendre des ressources qui existent déjà, on
utilise des blocs import.
Enfin, les secrets passent toujours par SOPS (chiffrés, donc versionnables sans risque), et
on lance toujours terraform fmt avant de committer (le hook s'en charge tout seul).
Carte rapide
Si tu cherches juste où aller, sans relire :
- Secrets / chiffrement :
sops.tf,secret.tf→ moduleskms,sops,secret - Réseau et machine :
network.tf→ modulesnetwork,security-groups,ec2 - Journaux :
cloudtrail.tf→ modulecloudtrail(etloggingpour les flux réseau) - Alertes par mail :
alerting.tf→ modulealerting - Droits / IAM :
iam.tf→ moduleiam - CI sans clé (OIDC) :
ci.tf→ modulegithub-oidc - État distant :
backend.tf→ moduletf-backend