S@yoo'S

Tutoriels • Retours d’expérience • Veille IT

AWS · DevOps · Labs · Linux

AWS avec Terraform : construire une infrastructure reproductible – Partie 1/2

20265 min de lecture

Objectif

Décrire une petite infrastructure AWS dans du code Terraform, la déployer et vérifier qu’elle correspond exactement à l’état attendu.

Question de départ : si l’infrastructure n’existait que dans la console AWS, comment la reprendre proprement et la rendre reproductible ?

Synopsis

Un VPC créé dans la console, un subnet ajouté plus tard, une règle réseau modifiée dans l’urgence : l’environnement peut fonctionner sans être réellement maîtrisé. Nous allons faire du code Terraform la source de vérité de cette infrastructure.

Prérequis

Le laboratoire est réalisé depuis une VM Debian 13 avec Git, AWS CLI et Terraform.

Figure 1 — Environnement DevOps utilisé pour le laboratoire.

Architecture du laboratoire

Nous partons d’une architecture volontairement simple : un VPC, un subnet public, une EC2 Amazon Linux 2023 et Nginx. Le but n’est pas encore la haute disponibilité, mais la reproductibilité.

Schéma — Architecture cible du laboratoire.

Accès AWS avec IAM Identity Center

Le lab est déployé dans le compte membre SAYOOS-LAB. L’accès passe par IAM Identity Center avec MFA, l’utilisateur sayoos-devops, le groupe devops-lab et le Permission Set SAYOOS-DevOps-PowerUser.

Schéma — Chaîne d’accès et de permissions utilisée pour le laboratoire.

aws configure sso –profile sayoos-lab
aws sso login –profile sayoos-lab
aws sts get-caller-identity –profile sayoos-lab

Figure 2 — Vérification de l’identité AWS ; les identifiants sensibles sont masqués.

Pour la session courante :

export AWS_PROFILE=sayoos-lab
export AWS_REGION=eu-west-3

Préparer le projet Terraform

mkdir -p ~/labs/sayoos-terraform-aws
cd ~/labs/sayoos-terraform-aws
git init
git branch -m main

Schéma — Organisation des fichiers du projet Terraform.

Protéger le dépôt Git

Le state Terraform, les plans locaux et le dossier .terraform ne doivent pas être versionnés. Le fichier .terraform.lock.hcl reste, lui, dans Git.

Schéma — Ce que Git doit conserver ou ignorer dans ce projet.

Déclarer Terraform et AWS

Dans terraform.tf : 

terraform {
  required_version = ">= 1.16.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}
Dans provider.tf : 

provider "aws" {
  region = var.aws_region

  default_tags {
    tags = {
      Project     = "SAYOOS-DevOps-Lab"
      Environment = "lab"
      ManagedBy   = "Terraform"
    }
  }
}

Variables du projet

variable "aws_region" {
  type    = string
  default = "eu-west-3"
}

variable "project_name" {
  type    = string
  default = "sayoos-devops-lab"
}

variable "vpc_cidr" {
  type    = string
  default = "10.10.0.0/16"
}

variable "public_subnet_cidr" {
  type    = string
  default = "10.10.10.0/24"
}

Construire le réseau AWS

Dans network.tf, nous déclarons le VPC, l’Internet Gateway, le subnet public et la route par défaut vers Internet.

resource "aws_vpc" "main" {
  cidr_block           = var.vpc_cidr
  enable_dns_support   = true
  enable_dns_hostnames = true
  tags = { Name = "${var.project_name}-vpc" }
}

resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id
  tags = { Name = "${var.project_name}-igw" }
}

resource "aws_subnet" "public" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = var.public_subnet_cidr
  map_public_ip_on_launch = true
  tags = { Name = "${var.project_name}-public-subnet" }
}

resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }
}

resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}

Autoriser le trafic HTTP

resource "aws_security_group" "web" {
  name        = "${var.project_name}-web-sg"
  description = "Autorise le trafic HTTP vers le serveur web"
  vpc_id      = aws_vpc.main.id
}

resource "aws_vpc_security_group_ingress_rule" "http" {
  security_group_id = aws_security_group.web.id
  cidr_ipv4          = "0.0.0.0/0"
  from_port          = 80
  to_port            = 80
  ip_protocol        = "tcp"
}

Nous n’ouvrons pas SSH : la configuration initiale du serveur sera automatisée par user_data.

Déployer EC2 et Nginx

Terraform recherche une AMI Amazon Linux 2023 récente, puis crée l’instance dans le subnet public.

data "aws_ami" "amazon_linux" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["al2023-ami-2023.*-kernel-6.1-x86_64"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

resource "aws_instance" "web" {
  ami                         = data.aws_ami.amazon_linux.id
  instance_type               = "t3.micro"
  subnet_id                   = aws_subnet.public.id
  vpc_security_group_ids      = [aws_security_group.web.id]
  associate_public_ip_address = true
  user_data_replace_on_change = true

  user_data = <<-EOF
    #!/bin/bash
    dnf install -y nginx
    cat > /usr/share/nginx/html/index.html <<'HTML'
    <h1>SAYOOS DevOps Lab</h1>
    <p>Infrastructure AWS provisionnée avec Terraform.</p>
    HTML

    systemctl enable --now nginx
  EOF

  tags = { Name = "${var.project_name}-web" }
}

Afficher les informations utiles

output "instance_public_ip" {
  value = aws_instance.web.public_ip
}

output "web_url" {
  value = "http://${aws_instance.web.public_ip}"
}

Initialiser, valider et planifier

terraform init
terraform fmt
terraform validate
terraform plan -out=tfplan

Le plan du lab annonce neuf créations et aucune modification ou destruction :
Plan: 9 to add, 0 to change, 0 to destroy.

Figure 3 — Revue du plan Terraform avant déploiement.

Premier déploiement

  terraform apply tfplan
Figure 4 — Premier déploiement réussi : neuf ressources créées.

Valider le service

curl -I "$(terraform output -raw web_url)"
terraform output -raw web_url
Figure 5 — La page Nginx est accessible depuis Internet.

Vérifier l’idempotence

  terraform plan
Résultat attendu : No changes. Your infrastructure matches the configuration.

Fin de la partie 1/2

Notre infrastructure fonctionne et Terraform considère qu’elle correspond au code. Il reste maintenant le test qui compte vraiment : la supprimer entièrement, puis vérifier que le même dépôt permet de remettre le service en ligne.

Dans la partie 2/2 : destruction, reconstruction, modification ciblée de l’EC2 et évolution de l’architecture vers un modèle plus proche de la production.

Partager

Infrastructure · Cloud · Automatisation · Retours d’expérience

© SAYOOS — Tous droits réservés.