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
-
Quelle est la différence entre ECS EC2 et Fargate ?
-
Qu'est-ce qu'une Task Definition ?
-
Combien de tasks minimum pour la haute disponibilité ?
-
Quel network mode est obligatoire pour Fargate ?
-
Comment économiser sur Fargate ?
Réponses
-
EC2 : vous gérez l'infrastructure. Fargate : serverless, AWS gère tout.
-
Blueprint qui décrit comment les conteneurs doivent s'exécuter (image, CPU, memory, ports, etc.).
-
Au moins 2 tasks dans des AZ différentes.
-
awsvpc - chaque task obtient une ENI avec sa propre IP.
-
Utiliser Fargate Spot (jusqu'à 70% d'économies), ARM64 (40% moins cher), right-sizing.
4 - Certification AWS
Examens pertinents
| Certification | Niveau |
|---|---|
| AWS Solutions Architect Associate | Fondamental |
| AWS Developer Associate | Fondamental |
| AWS DevOps Professional | Avancé |
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