Aller au contenu principal

AWS CodeDeploy


1 - Présentation

AWS CodeDeploy automatise les déploiements d'applications vers EC2, ECS, Lambda et les serveurs on-premises.


2 - Stratégies de déploiement

2.1 EC2/On-premises

StratégieDescription
AllAtOnceDéploie sur toutes les instances simultanément
HalfAtATimeDéploie sur 50% des instances à la fois
OneAtATimeDéploie une instance à la fois
CustomPourcentage ou nombre personnalisé

2.2 ECS

StratégieDescription
ECSAllAtOnceRemplace tout le trafic immédiatement
ECSLinear10PercentEvery1Minutes10% du trafic toutes les minutes
ECSCanary10Percent5Minutes10% pendant 5 min, puis 100%

2.3 Lambda

StratégieDescription
LambdaAllAtOnceTout le trafic immédiatement
LambdaLinear10PercentEvery1MinuteLinéaire 10%/min
LambdaCanary10Percent5MinutesCanary 10% pendant 5 min

3 - Configuration EC2

3.1 Installation de l'agent CodeDeploy

# Amazon Linux 2
sudo yum update -y
sudo yum install -y ruby wget
cd /home/ec2-user
wget https://aws-codedeploy-eu-west-1.s3.eu-west-1.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto
sudo service codedeploy-agent start
sudo service codedeploy-agent status

# Ubuntu
sudo apt update
sudo apt install -y ruby-full wget
cd /home/ubuntu
wget https://aws-codedeploy-eu-west-1.s3.eu-west-1.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto
sudo systemctl start codedeploy-agent
sudo systemctl enable codedeploy-agent

3.2 IAM Role pour EC2

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::mon-bucket-deploy/*",
"arn:aws:s3:::aws-codedeploy-eu-west-1/*"
]
}
]
}

3.3 appspec.yml pour EC2

# appspec.yml
version: 0.0
os: linux

files:
- source: /
destination: /var/www/html
overwrite: yes

permissions:
- object: /var/www/html
pattern: "**"
owner: www-data
group: www-data
mode: 755
type:
- file
- directory

hooks:
BeforeInstall:
- location: scripts/before_install.sh
timeout: 300
runas: root

AfterInstall:
- location: scripts/after_install.sh
timeout: 300
runas: root

ApplicationStart:
- location: scripts/start_server.sh
timeout: 300
runas: root

ValidateService:
- location: scripts/validate_service.sh
timeout: 300
runas: root

3.4 Scripts de déploiement

# scripts/before_install.sh
#!/bin/bash
set -e

# Arrêter le service
systemctl stop nginx || true

# Nettoyer l'ancien déploiement
rm -rf /var/www/html/*

echo "BeforeInstall completed"
# scripts/after_install.sh
#!/bin/bash
set -e

# Installer les dépendances
cd /var/www/html
npm install --production

# Configurer les permissions
chown -R www-data:www-data /var/www/html

echo "AfterInstall completed"
# scripts/start_server.sh
#!/bin/bash
set -e

# Démarrer le service
systemctl start nginx

echo "ApplicationStart completed"
# scripts/validate_service.sh
#!/bin/bash
set -e

# Vérifier que le service répond
for i in {1..30}; do
if curl -s http://localhost/ > /dev/null; then
echo "Service is healthy"
exit 0
fi
sleep 2
done

echo "Service validation failed"
exit 1

4 - Configuration ECS

4.1 appspec.yml pour ECS

# appspec.yml
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: "arn:aws:ecs:eu-west-1:123456789:task-definition/mon-app:10"
LoadBalancerInfo:
ContainerName: "app"
ContainerPort: 8080
PlatformVersion: "LATEST"
NetworkConfiguration:
AwsvpcConfiguration:
Subnets:
- subnet-abc123
- subnet-def456
SecurityGroups:
- sg-12345678
AssignPublicIp: DISABLED

Hooks:
- BeforeInstall: "arn:aws:lambda:eu-west-1:123456789:function:BeforeInstallHook"
- AfterInstall: "arn:aws:lambda:eu-west-1:123456789:function:AfterInstallHook"
- AfterAllowTestTraffic: "arn:aws:lambda:eu-west-1:123456789:function:TestTrafficHook"
- BeforeAllowTraffic: "arn:aws:lambda:eu-west-1:123456789:function:BeforeTrafficHook"
- AfterAllowTraffic: "arn:aws:lambda:eu-west-1:123456789:function:AfterTrafficHook"

4.2 Blue/Green ECS avec ALB

# CloudFormation
ECSDeploymentGroup:
Type: AWS::CodeDeploy::DeploymentGroup
Properties:
ApplicationName: !Ref CodeDeployApplication
DeploymentGroupName: ecs-deployment-group
ServiceRoleArn: !GetAtt CodeDeployRole.Arn
DeploymentConfigName: CodeDeployDefault.ECSLinear10PercentEvery1Minutes

DeploymentStyle:
DeploymentOption: WITH_TRAFFIC_CONTROL
DeploymentType: BLUE_GREEN

BlueGreenDeploymentConfiguration:
DeploymentReadyOption:
ActionOnTimeout: CONTINUE_DEPLOYMENT
WaitTimeInMinutes: 0
TerminateBlueInstancesOnDeploymentSuccess:
Action: TERMINATE
TerminationWaitTimeInMinutes: 5

ECSServices:
- ClusterName: !Ref ECSCluster
ServiceName: !GetAtt ECSService.Name

LoadBalancerInfo:
TargetGroupPairInfoList:
- TargetGroups:
- Name: !GetAtt BlueTargetGroup.TargetGroupName
- Name: !GetAtt GreenTargetGroup.TargetGroupName
ProdTrafficRoute:
ListenerArns:
- !Ref ALBListener
TestTrafficRoute:
ListenerArns:
- !Ref TestListener

5 - Configuration Lambda

5.1 appspec.yml pour Lambda

# appspec.yml
version: 0.0
Resources:
- MyLambdaFunction:
Type: AWS::Lambda::Function
Properties:
Name: ma-fonction
Alias: live
CurrentVersion: 1
TargetVersion: 2

Hooks:
- BeforeAllowTraffic: arn:aws:lambda:eu-west-1:123456789:function:PreTrafficHook
- AfterAllowTraffic: arn:aws:lambda:eu-west-1:123456789:function:PostTrafficHook

5.2 Hook de validation

# pre_traffic_hook.py
import boto3

codedeploy = boto3.client('codedeploy')
lambda_client = boto3.client('lambda')

def handler(event, context):
deployment_id = event['DeploymentId']
lifecycle_event_hook_execution_id = event['LifecycleEventHookExecutionId']

try:
# Tester la nouvelle version
response = lambda_client.invoke(
FunctionName='ma-fonction',
Qualifier='2', # Nouvelle version
InvocationType='RequestResponse',
Payload='{"test": true}'
)

if response['StatusCode'] == 200:
status = 'Succeeded'
else:
status = 'Failed'
except Exception as e:
print(f"Error: {e}")
status = 'Failed'

# Reporter le résultat
codedeploy.put_lifecycle_event_hook_execution_status(
deploymentId=deployment_id,
lifecycleEventHookExecutionId=lifecycle_event_hook_execution_id,
status=status
)

return status

6 - Rollback automatique

6.1 Configuration

# CloudFormation
DeploymentGroup:
Type: AWS::CodeDeploy::DeploymentGroup
Properties:
AutoRollbackConfiguration:
Enabled: true
Events:
- DEPLOYMENT_FAILURE
- DEPLOYMENT_STOP_ON_ALARM
- DEPLOYMENT_STOP_ON_REQUEST

AlarmConfiguration:
Enabled: true
IgnorePollAlarmFailure: false
Alarms:
- Name: !Ref HighErrorRateAlarm
- Name: !Ref HighLatencyAlarm

6.2 CloudWatch Alarms

HighErrorRateAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: HighErrorRate
MetricName: 5XXError
Namespace: AWS/ApplicationELB
Statistic: Sum
Period: 60
EvaluationPeriods: 2
Threshold: 10
ComparisonOperator: GreaterThanThreshold
Dimensions:
- Name: LoadBalancer
Value: !Ref ALB

7 - CLI et commandes

# Créer une application
aws deploy create-application \
--application-name mon-app \
--compute-platform Server

# Créer un deployment group
aws deploy create-deployment-group \
--application-name mon-app \
--deployment-group-name production \
--deployment-config-name CodeDeployDefault.OneAtATime \
--ec2-tag-filters Key=Environment,Value=Production,Type=KEY_AND_VALUE \
--service-role-arn arn:aws:iam::123456789:role/CodeDeployRole

# Déclencher un déploiement
aws deploy create-deployment \
--application-name mon-app \
--deployment-group-name production \
--s3-location bucket=mon-bucket,bundleType=zip,key=releases/v1.0.0.zip

# Suivre le déploiement
aws deploy get-deployment --deployment-id d-ABC123

# Stopper un déploiement
aws deploy stop-deployment --deployment-id d-ABC123

# Rollback
aws deploy create-deployment \
--application-name mon-app \
--deployment-group-name production \
--revision revisionType=S3,s3Location={bucket=mon-bucket,bundleType=zip,key=releases/v0.9.0.zip}

Résumé

Dans ce chapitre, nous avons appris :

  • Les stratégies de déploiement (AllAtOnce, HalfAtATime, Blue/Green)
  • La configuration pour EC2 avec appspec.yml et scripts
  • Les déploiements ECS Blue/Green
  • Les déploiements Lambda avec aliases
  • Le rollback automatique avec CloudWatch Alarms

Prochaine étape

Dans le prochain chapitre, nous verrons AWS CodePipeline pour orchestrer le CI/CD complet.

→ Chapitre suivant : AWS CodePipeline


← Retour à la table des matières