Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
137 changes: 134 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,139 @@ Votre mission (si vous l'acceptez) : Concevoir une architecture **API-driven** d
Séquence 4 : Documentation
Difficulté : Facile (~30 minutes)
---------------------------------------------------
**Complétez et documentez ce fichier README.md** pour nous expliquer comment utiliser votre solution.
Faites preuve de pédagogie et soyez clair dans vos expliquations et processus de travail.
Compte Rendu Technique : Orchestration Cloud avec LocalStack

Objectif : Créer une interface API permettant de piloter (allumer/éteindre) un serveur virtuel EC2 via une fonction Lambda, le tout simulé localement.

1. Préparation de l'Environnement

La première étape a consisté à isoler notre projet pour éviter les conflits de versions et simuler un environnement AWS réel.

Création d'une "bulle virtuelle" (venv) : Utilisation de python3 -m venv pour isoler les bibliothèques.

Installation des outils : Installation de awscli (pour commander le cloud), localstack (le simulateur) et boto3 (la bibliothèque Python pour AWS).

Configuration de l'identité : Paramétrage de clés d'accès fictives et d'une région par défaut (us-east-1) pour que l'outil AWS CLI accepte les commandes.

Code bash :
# Création et activation de l'environnement virtuel
python3 -m venv ./rep_localstack
source ./rep_localstack/bin/activate

# Installation des dépendances
pip install awscli localstack boto3

# Configuration des identifiants fictifs pour AWS CLI
aws configure set region us-east-1
aws configure set aws_access_key_id test
aws configure set aws_secret_access_key test

# Lancement du moteur LocalStack
export LOCALSTACK_AUTH_TOKEN="TON_TOKEN"
localstack start -d

2. Déploiement de l'Infrastructure (EC2)

Avant d'automatiser, nous avons dû créer la ressource à piloter.

Sélection de l'image (AMI) : Recherche dans le catalogue LocalStack pour trouver un identifiant d'image valide.

Lancement de l'instance : Exécution de la commande run-instances pour créer un serveur de type t2.micro.

Identification : Récupération de l'Instance ID (ex: i-d159f4d44bc8c2f4a), qui sert de "plaque d'immatriculation" unique pour nos futures commandes.

Code bash :
# Lister les images disponibles pour choisir une AMI
aws --endpoint-url=http://127.0.0.1:4566 ec2 describe-images --query "Images[*].{Name:Name,ID:ImageId}" --output table

# Lancer l'instance EC2 (en utilisant l'AMI choisie)
aws --endpoint-url=http://127.0.0.1:4566 ec2 run-instances --image-id ami-d159f4d4 --count 1 --instance-type t2.micro

# Récupérer l'ID de l'instance pour le script Python
aws --endpoint-url=http://127.0.0.1:4566 ec2 describe-instances --query "Reservations[*].Instances[*].InstanceId" --output text

3. Développement et Déploiement de la Lambda

La fonction Lambda agit comme le cerveau du projet. Nous avons rédigé un script Python nommé gestion_ec2.py.

Code Python : Utilisation de la bibliothèque boto3 pour envoyer des ordres start_instances et stop_instances.

Correction réseau : Pour que la Lambda puisse parler à LocalStack depuis son conteneur, nous avons utilisé l'URL spécifique http://localhost.localstack.cloud:4566.

Déploiement : Compression du script en fonction.zip et création de la fonction sur LocalStack.

Code bash :
# Compression du code source
zip fonction.zip gestion_ec2.py

# Création de la fonction Lambda
aws --endpoint-url=http://127.0.0.1:4566 lambda create-function \
--function-name PiloteEC2 \
--zip-file fileb://fonction.zip \
--handler gestion_ec2.lambda_handler \
--runtime python3.9 \
--role arn:aws:iam::000000000000:role/lambda-role

# Optimisation du timeout (pour éviter les erreurs 500)
aws --endpoint-url=http://127.0.0.1:4566 lambda update-function-configuration \
--function-name PiloteEC2 \
--timeout 10

4. Configuration de l'API Gateway

Pour rendre la Lambda accessible par une simple URL, nous avons configuré une passerelle API.

Étapes //

Création : Génération d'une API REST nommée "MonAPI-Pilote".
Ressource : Identification de la racine (/) de l'API.
Méthode : Configuration d'une méthode ANY pour accepter les requêtes
Intégration : Branchement de l'API sur la Lambda (Proxy).
Déploiement : Publication de l'API sur un environnement nommé test.

Code bash :
# 1. Créer l'API et noter l'ID généré (ex: rz2n11qhty)
aws --endpoint-url=http://127.0.0.1:4566 apigateway create-rest-api --name 'MonAPI-Pilote'

# 2. Récupérer l'ID de la ressource racine (/)
aws --endpoint-url=http://127.0.0.1:4566 apigateway get-resources --rest-api-id rz2n11qhty

# 3. Créer la méthode ANY
aws --endpoint-url=http://127.0.0.1:4566 apigateway put-method \
--rest-api-id rz2n11qhty --resource-id <ID_ROOT> --http-method ANY --authorization-type "NONE"

# 4. Intégrer la Lambda à l'API (Type Proxy)
aws --endpoint-url=http://127.0.0.1:4566 apigateway put-integration \
--rest-api-id rz2n11qhty --resource-id <ID_ROOT> --http-method ANY --type AWS_PROXY \
--integration-http-method POST \
--uri arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:000000000000:function:PiloteEC2/invocations

# 5. Déployer l'API sur le stage 'test'
aws --endpoint-url=http://127.0.0.1:4566 apigateway create-deployment --rest-api-id rz2n11qhty --stage-name test

5. Tests de Validation Final

Le pilotage se fait désormais via des requêtes HTTP simples (utilisant curl ou un navigateur).

Les commandes finales :
Démarrage : .../?action=start

Arrêt : .../?action=stop

Résultat final : L'envoi d'une requête URL retourne un message de succès JSON, et la vérification via describe-instances confirme que l'état de la machine passe de running à stopped en quelques secondes.

Code bash :
# Commande pour ARRETER l'instance
curl "http://127.0.0.1:4566/restapis/rz2n11qhty/test/_user_request_/?action=stop"

# Commande pour DEMARRER l'instance
curl "http://127.0.0.1:4566/restapis/rz2n11qhty/test/_user_request_/?action=start"

# Commande de vérification de l'état EC2
aws --endpoint-url=http://127.0.0.1:4566 ec2 describe-instances --query "Reservations[*].Instances[*].State.Name" --output text

CONCLUSION :
Ce projet démontre la puissance du Serverless. En combinant une API et une fonction Lambda, nous avons créé un outil d'administration capable de gérer des ressources d'infrastructure sans jamais avoir à se connecter manuellement à une console de gestion. C'est la base de l'automatisation moderne du Cloud (DevOps).

---------------------------------------------------
Evaluation
Expand All @@ -80,4 +211,4 @@ Cet atelier, **noté sur 20 points**, est évalué sur la base du barème suivan
- Fonctionnement conforme au scénario annoncé (4 points)
- Degré d'automatisation du projet (utilisation de Makefile ? script ? ...) (4 points)
- Qualité du Readme (lisibilité, erreur, ...) (4 points)
- Processus travail (quantité de commits, cohérence globale, interventions externes, ...) (4 points)
- Processus travail (quantité de commits, cohérence globale, interventions externes, ...) (4 points)
1 change: 1 addition & 0 deletions erreur.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"errorMessage":"2026-04-22T10:53:32Z fd09bcc5-9380-4efa-a900-71ef3c270d86 Task timed out after 3.00 seconds"}
Binary file added fonction.zip
Binary file not shown.
35 changes: 35 additions & 0 deletions gestion_ec2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import boto3
import json

def lambda_handler(event, context):
# 1. Connexion au service EC2 de LocalStack
# On précise l'URL locale car la Lambda tourne "dans" LocalStack
ec2 = boto3.client('ec2', endpoint_url='http://localhost.localstack.cloud:4566', region_name='us-east-1')

# 2. Identification de la cible
# REMPLACE CET ID PAR LE TIEN (celui qui commence par i-)
instance_id = "i-d159f4d44bc8c2f4a"

# 3. Récupération de l'action demandée (?action=start ou ?action=stop)
# Si rien n'est précisé, on choisit 'start' par défaut
params = event.get('queryStringParameters') or {}
action = params.get('action', 'start')

try:
if action == 'stop':
ec2.stop_instances(InstanceIds=[instance_id])
message = f"Succès : Instance {instance_id} en cours d'arrêt."
else:
ec2.start_instances(InstanceIds=[instance_id])
message = f"Succès : Instance {instance_id} en cours de démarrage."

return {
'statusCode': 200,
'body': json.dumps({'message': message})
}

except Exception as e:
return {
'statusCode': 500,
'body': json.dumps({'error': str(e)})
}
Loading