Aller au contenu principal

Exercices et Projets


1 - Exercices pratiques

Exercice 1 : Premier cluster et task

Objectif : Créer un cluster ECS et exécuter une task Fargate.

# Tâches :
# 1. Créer un cluster ECS
# 2. Créer une Task Definition pour nginx
# 3. Exécuter une task
# 4. Vérifier les logs
Solution
# 1. Créer le cluster
aws ecs create-cluster --cluster-name demo-cluster

# 2. Créer la task definition
cat > task-def.json << 'EOF'
{
"family": "nginx-demo",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512",
"executionRoleArn": "arn:aws:iam::ACCOUNT_ID:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"name": "nginx",
"image": "nginx:latest",
"essential": true,
"portMappings": [{"containerPort": 80}],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/nginx-demo",
"awslogs-region": "eu-west-1",
"awslogs-stream-prefix": "nginx",
"awslogs-create-group": "true"
}
}
}
]
}
EOF

aws ecs register-task-definition --cli-input-json file://task-def.json

# 3. Exécuter la task
aws ecs run-task \
--cluster demo-cluster \
--task-definition nginx-demo:1 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-xxx],securityGroups=[sg-xxx],assignPublicIp=ENABLED}"

# 4. Voir les logs
aws logs tail /ecs/nginx-demo --follow

Exercice 2 : Service avec ALB

Objectif : Déployer un service derrière un ALB.

Solution (CloudFormation)
AWSTemplateFormatVersion: '2010-09-09'

Resources:
ALB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Type: application
Subnets:
- !Ref PublicSubnet1
- !Ref PublicSubnet2
SecurityGroups:
- !Ref ALBSecurityGroup

TargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Port: 80
Protocol: HTTP
VpcId: !Ref VPC
TargetType: ip
HealthCheckPath: /

Listener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
LoadBalancerArn: !Ref ALB
Port: 80
Protocol: HTTP
DefaultActions:
- Type: forward
TargetGroupArn: !Ref TargetGroup

ECSService:
Type: AWS::ECS::Service
DependsOn: Listener
Properties:
Cluster: !Ref ECSCluster
TaskDefinition: !Ref TaskDefinition
DesiredCount: 2
LaunchType: FARGATE
NetworkConfiguration:
AwsvpcConfiguration:
Subnets:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
SecurityGroups:
- !Ref ServiceSecurityGroup
LoadBalancers:
- TargetGroupArn: !Ref TargetGroup
ContainerName: app
ContainerPort: 80

Exercice 3 : Auto Scaling

Objectif : Configurer l'auto scaling basé sur le CPU.

Solution
ScalableTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties:
MinCapacity: 2
MaxCapacity: 10
ResourceId: !Sub service/${ECSCluster}/${ECSService.Name}
ScalableDimension: ecs:service:DesiredCount
ServiceNamespace: ecs

CPUScalingPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties:
PolicyName: CPUScaling
PolicyType: TargetTrackingScaling
ScalingTargetId: !Ref ScalableTarget
TargetTrackingScalingPolicyConfiguration:
TargetValue: 70
PredefinedMetricSpecification:
PredefinedMetricType: ECSServiceAverageCPUUtilization
ScaleInCooldown: 300
ScaleOutCooldown: 60

Exercice 4 : Blue/Green Deployment

Objectif : Configurer un déploiement Blue/Green avec CodeDeploy.

Solution
# Service avec CodeDeploy
ECSService:
Type: AWS::ECS::Service
Properties:
DeploymentController:
Type: CODE_DEPLOY
LoadBalancers:
- TargetGroupArn: !Ref BlueTargetGroup
ContainerName: app
ContainerPort: 8080

# CodeDeploy
CodeDeployApplication:
Type: AWS::CodeDeploy::Application
Properties:
ComputePlatform: ECS

DeploymentGroup:
Type: AWS::CodeDeploy::DeploymentGroup
Properties:
ApplicationName: !Ref CodeDeployApplication
DeploymentConfigName: CodeDeployDefault.ECSLinear10PercentEvery1Minutes
ServiceRoleArn: !GetAtt CodeDeployRole.Arn
DeploymentStyle:
DeploymentOption: WITH_TRAFFIC_CONTROL
DeploymentType: BLUE_GREEN
ECSServices:
- ClusterName: !Ref ECSCluster
ServiceName: !GetAtt ECSService.Name
LoadBalancerInfo:
TargetGroupPairInfoList:
- TargetGroups:
- Name: !GetAtt BlueTargetGroup.TargetGroupName
- Name: !GetAtt GreenTargetGroup.TargetGroupName
ProdTrafficRoute:
ListenerArns:
- !Ref Listener

2 - Projet complet : Application Web 3-tiers

Architecture

Structure du projet

project/
├── infrastructure/
│ ├── vpc.yaml
│ ├── ecs-cluster.yaml
│ ├── alb.yaml
│ ├── services.yaml
│ └── database.yaml
├── services/
│ ├── web/
│ │ ├── Dockerfile
│ │ └── task-definition.json
│ └── api/
│ ├── Dockerfile
│ └── task-definition.json
└── deploy/
├── buildspec.yml
└── pipeline.yaml

Task Definition API

{
"family": "api-service",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "512",
"memory": "1024",
"executionRoleArn": "arn:aws:iam::ACCOUNT:role/ecsTaskExecutionRole",
"taskRoleArn": "arn:aws:iam::ACCOUNT:role/apiTaskRole",
"containerDefinitions": [
{
"name": "api",
"image": "ACCOUNT.dkr.ecr.eu-west-1.amazonaws.com/api:latest",
"essential": true,
"portMappings": [
{"containerPort": 8080, "protocol": "tcp"}
],
"environment": [
{"name": "NODE_ENV", "value": "production"},
{"name": "PORT", "value": "8080"}
],
"secrets": [
{
"name": "DATABASE_URL",
"valueFrom": "arn:aws:secretsmanager:eu-west-1:ACCOUNT:secret:db-url"
},
{
"name": "REDIS_URL",
"valueFrom": "arn:aws:secretsmanager:eu-west-1:ACCOUNT:secret:redis-url"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/api-service",
"awslogs-region": "eu-west-1",
"awslogs-stream-prefix": "api"
}
},
"healthCheck": {
"command": ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"],
"interval": 30,
"timeout": 5,
"retries": 3,
"startPeriod": 60
}
}
]
}

Pipeline CI/CD

# buildspec.yml
version: 0.2

phases:
pre_build:
commands:
- aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_REPO
- COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)

build:
commands:
- docker build -t $ECR_REPO:$COMMIT_HASH .
- docker push $ECR_REPO:$COMMIT_HASH

post_build:
commands:
- printf '{"ImageURI":"%s"}' $ECR_REPO:$COMMIT_HASH > imageDetail.json
- cat appspec.yml
- cat taskdef.json

artifacts:
files:
- imageDetail.json
- appspec.yml
- taskdef.json

3 - Quiz de révision

  1. Quelle est la différence entre ECS EC2 et Fargate ?

  2. Qu'est-ce qu'une Task Definition ?

  3. Combien de tasks minimum pour la haute disponibilité ?

  4. Quel network mode est obligatoire pour Fargate ?

  5. Comment économiser sur Fargate ?

Réponses
  1. EC2 : vous gérez l'infrastructure. Fargate : serverless, AWS gère tout.

  2. Blueprint qui décrit comment les conteneurs doivent s'exécuter (image, CPU, memory, ports, etc.).

  3. Au moins 2 tasks dans des AZ différentes.

  4. awsvpc - chaque task obtient une ENI avec sa propre IP.

  5. Utiliser Fargate Spot (jusqu'à 70% d'économies), ARM64 (40% moins cher), right-sizing.


4 - Certification AWS

Examens pertinents

CertificationNiveau
AWS Solutions Architect AssociateFondamental
AWS Developer AssociateFondamental
AWS DevOps ProfessionalAvancé

Ressources


Résumé du cours

Félicitations ! Vous avez complété le cours AWS ECS et Fargate.

Vous maîtrisez maintenant :

  • Les concepts ECS (clusters, tasks, services)
  • Les Task Definitions et leur configuration
  • Le networking et load balancing
  • Fargate pour les conteneurs serverless
  • L'auto scaling des services
  • Le monitoring avec CloudWatch
  • Les bonnes pratiques de production

Prochaines étapes

  • Pratiquer avec des projets réels
  • Explorer EKS pour Kubernetes
  • Étudier AWS App Runner pour plus de simplicité
  • Passer les certifications AWS

← Retour à la table des matières