Aller au contenu

TP 23 : Importer une infrastructure existante

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

  • distinguer la commande terraform import du bloc import déclaratif ;
  • écrire un bloc import pour rattacher une ressource existante au state ;
  • générer automatiquement la configuration avec -generate-config-out ;
  • compléter la configuration générée pour obtenir un terraform plan sans modification.
  • Terraform >= 1.5 (le bloc import déclaratif et -generate-config-out sont disponibles depuis la 1.5).
  • Un compte AWS et la CLI aws configurée.

InfraBank possède des ressources créées « à la main » dans la console avant l’adoption de Terraform. Objectif : reprendre ces ressources sous gestion Terraform sans les recréer, pour éviter toute interruption.

Étape 1 : Créer une ressource « hors Terraform »

Section intitulée « Étape 1 : Créer une ressource « hors Terraform » »

Pour simuler l’existant, créez un bucket S3 directement avec la CLI (donc inconnu de Terraform) :

Fenêtre de terminal
BUCKET="infrabank-legacy-$(date +%s)"
aws s3api create-bucket \
--bucket "$BUCKET" \
--region eu-west-3 \
--create-bucket-configuration LocationConstraint=eu-west-3
aws s3api put-bucket-tagging \
--bucket "$BUCKET" \
--tagging 'TagSet=[{Key=owner,Value=legacy},{Key=managed_by,Value=console}]'
echo "$BUCKET"
versions.tf
terraform {
required_version = ">= 1.5"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.60"
}
}
}
provider "aws" {
region = "eu-west-3"
}
Fenêtre de terminal
terraform init

Le bloc import indique à Terraform quelle ressource cible (to) correspond à quel identifiant réel (id). Remplacez le nom du bucket.

import.tf
import {
to = aws_s3_bucket.legacy
id = "infrabank-legacy-XXXXXXXXXX"
}

Contrairement à terraform import (impératif, une ressource à la fois, ne génère pas de code), le bloc import est déclaratif : il vit dans le code, passe par le plan, et peut générer la configuration.

Fenêtre de terminal
terraform plan -generate-config-out=generated.tf

Terraform lit l’état réel du bucket et écrit une ressource aws_s3_bucket.legacy dans generated.tf, avec tous les attributs découverts. Inspectez le fichier :

Fenêtre de terminal
cat generated.tf

Vous y trouverez notamment le bucket, les tags, et probablement des attributs par défaut ou calculés.

Étape 5 : Nettoyer et compléter la configuration

Section intitulée « Étape 5 : Nettoyer et compléter la configuration »

La configuration générée est un point de départ, pas un livrable. Déplacez la ressource dans main.tf, retirez les attributs en lecture seule ou calculés que le provider renvoie mais n’accepte pas en entrée (ils provoqueraient une erreur), et gardez ce qui décrit réellement l’intention :

main.tf
resource "aws_s3_bucket" "legacy" {
bucket = "infrabank-legacy-XXXXXXXXXX"
tags = {
owner = "legacy"
managed_by = "console"
}
}

Supprimez generated.tf une fois le contenu recopié :

Fenêtre de terminal
rm generated.tf
Fenêtre de terminal
terraform apply

Le plan doit indiquer 1 à importer, 0 à ajouter, 0 à modifier, 0 à détruire :

Plan: 1 to import, 0 to add, 0 to change, 0 to destroy.

Confirmez avec yes. La ressource est désormais dans le state.

C’est le critère de réussite : un second plan ne doit rien proposer.

Fenêtre de terminal
terraform plan
# No changes. Your infrastructure matches the configuration.

Si le plan propose une modification, un attribut de votre configuration diffère de la réalité (souvent des tags, un acl implicite ou une politique). Alignez le code sur l’existant jusqu’à obtenir un plan vide.

Une fois l’import réussi et le state à jour, le bloc import n’a plus de rôle. Supprimez-le pour garder un code propre :

Fenêtre de terminal
rm import.tf
terraform plan # toujours aucun changement
  • terraform state list contient aws_s3_bucket.legacy.
  • terraform plan renvoie « No changes ».
  • Le bloc import a été retiré sans impact.
Fenêtre de terminal
terraform destroy -auto-approve