TP13 : Cloud AWS local avec Floci et Terraform avancé

Apprendre AWS sans carte bancaire, sans compte et sans risque de facture : Floci est un émulateur AWS local, libre (licence MIT) et léger, qui expose les API AWS sur http://localhost:4566. Il s’est imposé comme alternative à LocalStack Community, qui exige un jeton d’authentification depuis mars 2026. Les outils AWS habituels (AWS CLI, SDK, Terraform) fonctionnent sans modification : il suffit de changer le endpoint.

Ce TP prolonge le TP6 : après le provider Docker, vous pilotez des services « cloud » avec le provider AWS, puis vous passez aux pratiques Terraform d’équipe : modules, environnements, state distant verrouillé, scan IaC et OpenTofu.


Fichiers de départ : lambda.zip, sdk-demo.zip, terraform-starter.zip

1. Objectifs pédagogiques

À l’issue du TP, vous serez capable de :

  • lancer Floci et utiliser AWS CLI et le SDK JavaScript v3 contre un endpoint local ;
  • manipuler S3, SQS, DynamoDB, Lambda et Secrets Manager ;
  • configurer le provider Terraform AWS pour Floci et créer des ressources sécurisées ;
  • factoriser le code en modules et le décliner en dev / staging / prod ;
  • stocker le state dans un backend S3 verrouillé et expliquer pourquoi ;
  • détecter une mauvaise configuration avec Checkov ou Trivy IaC, et rejouer le tout avec OpenTofu.

Les images de cette page sont des schémas explicatifs, pas des captures d’écran.

2. Environnement du TP

  • VM de lab Ubuntu Server 26.04 avec Docker et Terraform (TP6), Node.js 24, unzip.

  • Installer AWS CLI v2 :

    curl -sSL "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o awscliv2.zip
    unzip -q awscliv2.zip && sudo ./aws/install && aws --version
  • Démarrer Floci. Le socket Docker est monté car Lambda exécute les fonctions dans des conteneurs :

    docker run -d --name floci -p 4566:4566 \
      -v /var/run/docker.sock:/var/run/docker.sock floci/floci
    docker logs floci

Floci : AWS CLI, SDK et Terraform pointent vers localhost:4566 Floci : AWS CLI, SDK et Terraform pointent vers localhost:4566

3. Partie 1 : AWS CLI contre Floci

  • Créer un profil dédié avec des identifiants fictifs et le endpoint local :

    aws configure set aws_access_key_id test --profile floci
    aws configure set aws_secret_access_key test --profile floci
    aws configure set region us-east-1 --profile floci
    aws configure set endpoint_url http://localhost:4566 --profile floci
    export AWS_PROFILE=floci
    aws sts get-caller-identity          # noter l'Account ID simulé

    Avec endpoint_url dans le profil, l’option --endpoint-url devient inutile. Vérifiez toujours votre profil avant une commande destructive : la même commande sur un vrai compte AWS aurait des effets réels.

  • S3 : créer un bucket, envoyer un fichier, le lister, le récupérer :

    aws s3 mb s3://tp13-demo
    echo "Bonjour Floci" > hello.txt
    aws s3 cp hello.txt s3://tp13-demo/
    aws s3 ls s3://tp13-demo/
    aws s3 cp s3://tp13-demo/hello.txt -
  • SQS : créer une file, envoyer puis lire un message :

    QURL=$(aws sqs create-queue --queue-name tp13-demo --query QueueUrl --output text)
    aws sqs send-message --queue-url "$QURL" --message-body '{"event":"test"}'
    aws sqs receive-message --queue-url "$QURL"
  • DynamoDB : créer une table visits (clé id de type S, mode PAY_PER_REQUEST), insérer deux éléments avec put-item et les relire avec scan.

  • Secrets Manager : créer le secret tp13/demo/api-key, puis le relire avec get-secret-value.

  • Lambda : empaqueter lambda/index.mjs, créer la fonction et l’invoquer :

    cd lambda && zip function.zip index.mjs && cd ..
    ACCOUNT=$(aws sts get-caller-identity --query Account --output text)
    aws lambda create-function --function-name hello --runtime nodejs22.x \
      --handler index.handler --zip-file fileb://lambda/function.zip \
      --role arn:aws:iam::$ACCOUNT:role/lambda-role
    aws lambda invoke --function-name hello --payload '{"name":"Ada"}' \
      --cli-binary-format raw-in-base64-out out.json && cat out.json

4. Partie 2 : SDK JavaScript

  • Lancer sdk-demo/ : il écrit et liste des objets dans tp13-demo.

    cd sdk-demo && npm install && npm start
  • Compléter le TODO : envoyer un message JSON dans la file SQS (QUEUE_URL=$QURL npm start), puis le lire avec AWS CLI.

  • Ajouter Floci comme service dans un compose.yaml avec le programme du SDK. Quelle valeur prend AWS_ENDPOINT_URL à l’intérieur du réseau Compose ?

5. Partie 3 : Terraform avec le provider AWS

  • Ouvrir terraform-starter/providers.tf et expliquer chaque option skip_*, s3_use_path_style et le bloc endpoints.

  • Compléter main.tf : bucket versionné, non public, chiffré ; file SQS avec file de lettres mortes ; table DynamoDB ; secret Secrets Manager (valeur passée par une variable sensitive).

  • Cycle complet :

    cd terraform-starter
    terraform init && terraform fmt && terraform validate
    terraform plan -out tfplan
    terraform apply tfplan
    terraform output
    aws s3api get-bucket-versioning --bucket tp13-uploads-dev
    aws sqs list-queues && aws dynamodb list-tables
  • Supprimer à la main la table DynamoDB avec AWS CLI, puis relancer terraform plan : comment Terraform réagit-il à cette dérive (drift) ?

6. Partie 4 : Modules, environnements et state distant

State distant dans S3 avec verrouillage State distant dans S3 avec verrouillage

Notion Explication
State Fichier JSON qui associe chaque ressource du code à un objet réel (identifiants, attributs). Sans lui, Terraform ne sait plus ce qu’il gère.
Backend distant Stocke le state hors du poste (S3, GCS, Terraform Cloud…) pour le partager en équipe et le sauvegarder.
Verrou Empêche deux apply simultanés de corrompre le state.
Données sensibles Le state contient en clair des valeurs (mots de passe, clés) : chiffrez-le et restreignez son accès.
  • Déplacer le bucket sécurisé dans le module modules/secure-bucket/ et l’appeler deux fois (uploads, backups). Utiliser terraform state mv (ou un bloc moved) pour éviter la destruction des ressources existantes.

  • Ajouter une validation sur var.environment et créer dev.tfvars, staging.tfvars, prod.tfvars.

  • Bootstrap du backend : créer le bucket tp13-tfstate (versionné) avec AWS CLI.

  • Renommer backend.tf.example en backend.tf, puis migrer le state :

    terraform init -migrate-state
    aws s3 ls s3://tp13-tfstate/envs/dev/
  • Tester le verrou : lancer terraform apply dans un terminal sans répondre à la confirmation, puis terraform plan dans un second terminal. Le second doit afficher Error acquiring the state lock.

    Si votre version de Floci ne gère pas les écritures conditionnelles S3 nécessaires à use_lockfile, utilisez l’alternative dynamodb_table (table avec une clé LockID de type S, endpoint dynamodb ajouté au backend) et notez-le dans votre rendu.

  • Séparer les environnements avec une clé de state par environnement (envs/dev/…, envs/prod/…) via terraform init -backend-config="key=envs/prod/terraform.tfstate" -reconfigure, ou avec les workspaces. Comparer les deux approches.

7. Partie 5 : Scan IaC et OpenTofu

  • Analyser le code avec Checkov et Trivy :

    docker run --rm -v "$PWD:/tf" bridgecrew/checkov -d /tf --quiet
    docker run --rm -v "$PWD:/tf" aquasec/trivy:latest config /tf
  • Introduire une mauvaise configuration (block_public_acls = false, chiffrement supprimé) et vérifier qu’elle est détectée. Ajouter ce scan au Jenkinsfile (TP9) ou au workflow (TP10) avec un code retour bloquant.

  • Installer OpenTofu (instructions officielles) et rejouer le cycle sur une copie du projet :

    tofu init && tofu plan && tofu apply

    Comparer : licence, compatibilité des providers et du state, fonctionnalités propres (chiffrement du state côté client avec OpenTofu).

  • Rédiger une comparaison courte Floci / LocalStack / AWS réel : licence, services couverts, fidélité, coût, usage en CI.

  • Nettoyer : terraform destroy -var-file=dev.tfvars, puis docker rm -f floci.

Défi

  1. Factoriser les trois environnements avec Terragrunt (terragrunt.hcl racine qui génère le backend, un dossier par environnement).
  2. Créer la Lambda avec Terraform (archive_file + aws_lambda_function) et la déclencher par la file SQS (aws_lambda_event_source_mapping).

8. Livrables

Captures à déposer dans captures/ :

Fichier Contenu attendu
floci-cli.png Commandes S3, SQS, DynamoDB et lambda invoke réussies
sdk-demo.png Programme SDK : objets listés et message SQS envoyé
terraform-apply.png terraform apply puis vérification avec AWS CLI
drift.png terraform plan après suppression manuelle de la table
remote-state.png State présent dans s3://tp13-tfstate/envs/dev/
state-lock.png Erreur Error acquiring the state lock
iac-scan.png Checkov ou Trivy détectant la mauvaise configuration
opentofu.png tofu apply réussi

Ainsi que le projet Terraform (*.tf, .terraform.lock.hcl, *.tfvars sans secret) et la comparaison Floci / LocalStack / AWS. Pas de terraform.tfstate.