AWS CodePipeline
Le service d'intégration et de déploiement continus entièrement géré d'AWS qui automatise les phases de construction, de test et de déploiement de vos applications.
Qu'est-ce qu'AWS CodePipeline ?
Imaginez une chaîne de montage dans une usine, où chaque étape de la fabrication d'un produit est automatisée et enchaînée. AWS CodePipeline fonctionne de manière similaire, mais pour les logiciels.
AWS CodePipeline est un service cloud qui automatise tout le processus de mise à jour et de déploiement de vos applications. C'est comme un chef d'orchestre qui coordonne tous les aspects nécessaires pour faire passer votre code de l'écriture à la mise en production.
Pourquoi est-ce important ?
Rapidité
Réduit considérablement le temps nécessaire pour déployer de nouvelles fonctionnalités ou corriger des bugs, en automatisant des tâches qui prendraient des heures ou des jours manuellement.
Fiabilité
Vérifie automatiquement la qualité du code et détecte les problèmes avant qu'ils n'atteignent les utilisateurs, améliorant ainsi la stabilité des applications.
En résumé, AWS CodePipeline est l'outil qui permet aux entreprises de livrer plus rapidement et plus souvent leurs applications avec une qualité constante et élevée, en éliminant les erreurs humaines et en automatisant les étapes répétitives.
Fonctionnement technique
AWS CodePipeline est un service d'intégration et de déploiement continus (CI/CD) entièrement géré qui aide à automatiser les pipelines de publication pour des mises à jour d'applications et d'infrastructures rapides et fiables. CodePipeline compile le code, exécute les tests et prépare les modifications pour le déploiement chaque fois qu'une modification est apportée au code source.
Concepts fondamentaux
Structure d'un pipeline
Un pipeline dans AWS CodePipeline est composé de plusieurs éléments :
- Étapes (Stages) : Groupes d'actions liées, comme les étapes de construction, de test ou de déploiement
- Actions : Tâches exécutées dans une étape, comme la compilation du code ou le déploiement vers des environnements
- Transitions : Connexions entre les étapes, qui peuvent être automatiques ou manuelles
- Artefacts : Fichiers de sortie produits par les étapes et utilisés comme entrée pour les étapes suivantes
- Révisions : Versions des sources qui déclenchent l'exécution du pipeline
Définition d'un pipeline avec CloudFormation
Voici comment définir un pipeline complet AWS CodePipeline en utilisant CloudFormation, depuis la source jusqu'au déploiement :
# Exemple de configuration AWS CodePipeline avec CloudFormation
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Pipeline CI/CD pour une application Node.js'
Resources:
# Bucket S3 pour stocker les artefacts du pipeline
ArtifactBucket:
Type: AWS::S3::Bucket
Properties:
VersioningConfiguration:
Status: Enabled
# Rôle IAM pour le pipeline
CodePipelineServiceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: codepipeline.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AWSCodeStarFullAccess'
# Pipeline CI/CD
AppPipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
ArtifactStore:
Type: S3
Location: !Ref ArtifactBucket
RoleArn: !GetAtt CodePipelineServiceRole.Arn
Stages:
# Étape 1: Source - Récupération du code depuis GitHub
- Name: Source
Actions:
- Name: Source
ActionTypeId:
Category: Source
Owner: ThirdParty
Provider: GitHub
Version: '1'
Configuration:
Owner: '{github-account}'
Repo: '{repository-name}'
Branch: main
OAuthToken: '{{resolve:secretsmanager:GitHub/OAuthToken:SecretString:OAuthToken}}'
OutputArtifacts:
- Name: SourceCode
# Étape 2: Build - Construction et tests avec CodeBuild
- Name: Build
Actions:
- Name: BuildAndTest
ActionTypeId:
Category: Build
Owner: AWS
Provider: CodeBuild
Version: '1'
Configuration:
ProjectName: !Ref BuildProject
InputArtifacts:
- Name: SourceCode
OutputArtifacts:
- Name: BuildOutput
# Étape 3: Deploy - Déploiement vers l'environnement de staging
- Name: DeployToStaging
Actions:
- Name: DeployToECS
ActionTypeId:
Category: Deploy
Owner: AWS
Provider: ECS
Version: '1'
Configuration:
ClusterName: staging-cluster
ServiceName: webapp-service
FileName: taskdef.json
InputArtifacts:
- Name: BuildOutput
# Étape 4: Approbation manuelle avant déploiement en production
- Name: Approval
Actions:
- Name: ManualApproval
ActionTypeId:
Category: Approval
Owner: AWS
Provider: Manual
Version: '1'
Configuration:
NotificationArn: !Ref ApprovalTopic
CustomData: "Veuillez examiner et approuver le déploiement en production"
# Étape 5: Deploy - Déploiement vers l'environnement de production
- Name: DeployToProduction
Actions:
- Name: DeployToECS
ActionTypeId:
Category: Deploy
Owner: AWS
Provider: ECS
Version: '1'
Configuration:
ClusterName: production-cluster
ServiceName: webapp-service
FileName: taskdef.json
InputArtifacts:
- Name: BuildOutput
# Projet CodeBuild pour la phase de build
BuildProject:
Type: AWS::CodeBuild::Project
Properties:
Artifacts:
Type: CODEPIPELINE
Environment:
Type: LINUX_CONTAINER
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0
ServiceRole: !GetAtt CodeBuildServiceRole.Arn
Source:
Type: CODEPIPELINE
BuildSpec: buildspec.yml
# Rôle IAM pour CodeBuild
CodeBuildServiceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: codebuild.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AmazonECR-FullAccess'
- 'arn:aws:iam::aws:policy/AmazonS3FullAccess'
# SNS Topic pour les notifications d'approbation
ApprovalTopic:
Type: AWS::SNS::Topic
Properties:
DisplayName: Pipeline Approval Notifications
Outputs:
PipelineURL:
Description: URL pour accéder au pipeline
Value: !Sub https://console.aws.amazon.com/codepipeline/home?region=${AWS::Region}#/view/${AppPipeline}
Configuration du processus de build
Le fichier buildspec définit les étapes qu'AWS CodeBuild exécute lors de la phase de build du pipeline :
# buildspec.yml - Configuration de build pour AWS CodeBuild
version: 0.2
phases:
install:
runtime-versions:
nodejs: 14
commands:
- echo Installation des dépendances...
- npm install
pre_build:
commands:
- echo Exécution des tests...
- npm test
- echo Connexion à ECR...
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
- COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
- IMAGE_TAG=$COMMIT_HASH:$CODEBUILD_BUILD_NUMBER
build:
commands:
- echo Construction de l'application...
- npm run build
- echo Construction de l'image Docker...
- docker build -t $REPOSITORY_URI:latest .
- docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
post_build:
commands:
- echo Envoi de l'image vers ECR...
- docker push $REPOSITORY_URI:latest
- docker push $REPOSITORY_URI:$IMAGE_TAG
- echo Création du fichier de définition de tâche ECS...
- aws ecs describe-task-definition --task-definition webapp-task --query taskDefinition > taskdef.json
- echo Mise à jour du fichier de définition de tâche avec la nouvelle image...
- sed -i "s|<IMAGE>|$REPOSITORY_URI:$IMAGE_TAG|g" taskdef.json
artifacts:
files:
- taskdef.json
- appspec.yml
- scripts/*
cache:
paths:
- 'node_modules/**/*'
Création d'un pipeline avec l'AWS CLI
Pour les équipes qui préfèrent l'automatisation complète, voici comment créer un pipeline via l'interface en ligne de commande AWS :
# Création d'un pipeline à l'aide de l'AWS CLI
# 1. Créer un bucket S3 pour les artefacts
aws s3 mb s3://my-app-pipeline-artifacts
# 2. Créer un fichier de définition du pipeline au format JSON
cat > pipeline-definition.json << EOF
{
"pipeline": {
"name": "MyApplicationPipeline",
"roleArn": "arn:aws:iam::123456789012:role/AWSCodePipelineServiceRole",
"artifactStore": {
"type": "S3",
"location": "my-app-pipeline-artifacts"
},
"stages": [
{
"name": "Source",
"actions": [
{
"name": "Source",
"actionTypeId": {
"category": "Source",
"owner": "AWS",
"provider": "CodeStarSourceConnection",
"version": "1"
},
"configuration": {
"ConnectionArn": "arn:aws:codestar-connections:region:account-id:connection/connection-id",
"FullRepositoryId": "my-github-username/my-repository",
"BranchName": "main"
},
"outputArtifacts": [
{
"name": "SourceCode"
}
]
}
]
},
{
"name": "Build",
"actions": [
{
"name": "BuildAction",
"actionTypeId": {
"category": "Build",
"owner": "AWS",
"provider": "CodeBuild",
"version": "1"
},
"configuration": {
"ProjectName": "my-app-build-project"
},
"inputArtifacts": [
{
"name": "SourceCode"
}
],
"outputArtifacts": [
{
"name": "BuildOutput"
}
]
}
]
},
{
"name": "Deploy",
"actions": [
{
"name": "DeployAction",
"actionTypeId": {
"category": "Deploy",
"owner": "AWS",
"provider": "ElasticBeanstalk",
"version": "1"
},
"configuration": {
"ApplicationName": "my-app",
"EnvironmentName": "my-app-prod"
},
"inputArtifacts": [
{
"name": "BuildOutput"
}
]
}
]
}
]
}
}
EOF
# 3. Créer le pipeline
aws codepipeline create-pipeline --cli-input-json file://pipeline-definition.json
# 4. Démarrer l'exécution du pipeline manuellement
aws codepipeline start-pipeline-execution --name MyApplicationPipeline
Infrastructure as Code avec AWS CDK
AWS CDK (Cloud Development Kit) permet de définir des pipelines en utilisant des langages de programmation comme TypeScript :
// Définition d'un pipeline AWS CodePipeline avec AWS CDK
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as codepipeline from 'aws-cdk-lib/aws-codepipeline';
import * as codepipeline_actions from 'aws-cdk-lib/aws-codepipeline-actions';
import * as codebuild from 'aws-cdk-lib/aws-codebuild';
import * as ecr from 'aws-cdk-lib/aws-ecr';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as iam from 'aws-cdk-lib/aws-iam';
export class CdkPipelineStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Création d'un repository ECR pour stocker les images Docker
const repository = new ecr.Repository(this, 'Repository', {
repositoryName: 'my-app-repository',
removalPolicy: cdk.RemovalPolicy.DESTROY,
});
// Création d'un cluster ECS pour le déploiement
const cluster = new ecs.Cluster(this, 'Cluster', {
clusterName: 'my-app-cluster',
});
// Définition des artefacts pour le pipeline
const sourceOutput = new codepipeline.Artifact('SourceCode');
const buildOutput = new codepipeline.Artifact('BuildOutput');
// Création du projet CodeBuild pour la phase de build
const buildProject = new codebuild.PipelineProject(this, 'BuildProject', {
environment: {
buildImage: codebuild.LinuxBuildImage.STANDARD_5_0,
privileged: true, // Nécessaire pour les builds Docker
},
environmentVariables: {
REPOSITORY_URI: {
value: repository.repositoryUri,
},
CLUSTER_NAME: {
value: cluster.clusterName,
},
},
buildSpec: codebuild.BuildSpec.fromObject({
version: '0.2',
phases: {
pre_build: {
commands: [
'echo Logging in to Amazon ECR...',
'aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $REPOSITORY_URI',
'COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)',
'IMAGE_TAG=$COMMIT_HASH:$CODEBUILD_BUILD_NUMBER',
],
},
build: {
commands: [
'echo Building the Docker image...',
'docker build -t $REPOSITORY_URI:latest .',
'docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG',
],
},
post_build: {
commands: [
'echo Pushing the Docker image...',
'docker push $REPOSITORY_URI:latest',
'docker push $REPOSITORY_URI:$IMAGE_TAG',
'echo Writing image definition file...',
'aws ecs describe-task-definition --task-definition my-app-task --query taskDefinition > taskdef.json',
'echo "{\"ImageURI\":\""$REPOSITORY_URI:$IMAGE_TAG"\\"}" > imageDefinition.json',
],
},
},
artifacts: {
files: [
'taskdef.json',
'imageDefinition.json',
'appspec.yaml',
],
},
}),
});
// Ajout des permissions nécessaires au projet CodeBuild
repository.grantPullPush(buildProject);
buildProject.addToRolePolicy(new iam.PolicyStatement({
actions: ['ecs:DescribeTaskDefinition'],
resources: ['*'],
}));
// Création du pipeline
const pipeline = new codepipeline.Pipeline(this, 'Pipeline', {
pipelineName: 'my-app-pipeline',
crossAccountKeys: false,
});
// Ajout de l'étape Source
pipeline.addStage({
stageName: 'Source',
actions: [
new codepipeline_actions.GitHubSourceAction({
actionName: 'GitHub_Source',
owner: 'owner-name',
repo: 'repo-name',
branch: 'main',
oauthToken: cdk.SecretValue.secretsManager('github-token'),
output: sourceOutput,
}),
],
});
// Ajout de l'étape Build
pipeline.addStage({
stageName: 'Build',
actions: [
new codepipeline_actions.CodeBuildAction({
actionName: 'Build',
project: buildProject,
input: sourceOutput,
outputs: [buildOutput],
}),
],
});
// Ajout de l'étape Deploy
pipeline.addStage({
stageName: 'Deploy',
actions: [
new codepipeline_actions.EcsDeployAction({
actionName: 'DeployToECS',
service: ecs.FargateService.fromFargateServiceAttributes(this, 'ImportedService', {
serviceArn: 'arn:aws:ecs:region:account:service/cluster-name/service-name',
cluster,
}),
imageFile: buildOutput.atPath('imageDefinition.json'),
}),
],
});
// Outputs pour faciliter l'accès aux ressources
new cdk.CfnOutput(this, 'PipelineConsoleLink', {
value: `https://${cdk.Aws.REGION}.console.aws.amazon.com/codesuite/codepipeline/pipelines/${pipeline.pipelineName}/view`,
description: 'Lien direct vers la console CodePipeline',
});
}
}
Intégrations clés
- Source : AWS CodeCommit, GitHub, BitBucket, Amazon S3
- Build : AWS CodeBuild, Jenkins
- Test : AWS CodeBuild, AWS Device Farm, outils tiers comme BlazeMeter
- Deploy : AWS CodeDeploy, AWS Elastic Beanstalk,
Amazon ECS,
Amazon S3,
AWS CloudFormation
- Approbation : Approbations manuelles avec Amazon SNS
- Invoke :
AWS Lambda,
AWS Step Functions
Bonnes pratiques
- Sécurité des artefacts : Activer le versioning et le chiffrement des buckets S3 stockant les artefacts
- Approches multi-environnements : Utiliser des étapes séparées pour les environnements de développement, staging et production
- Approbations stratégiques : Mettre en place des approbations manuelles avant les déploiements critiques
- Notifications : Configurer des alertes SNS pour les succès et échecs des pipelines
- Tests automatisés : Intégrer des tests unitaires, d'intégration et de sécurité directement dans le pipeline
- Infrastructure as Code : Gérer les pipelines eux-mêmes avec
CloudFormation ou AWS CDK
Cas d'usage
Applications web modernes
Automatisation du flux complet depuis le commit du code jusqu'au déploiement d'applications React, Angular ou Vue sur des services comme S3, CloudFront ou Amplify.
Applications conteneurisées
Flux CI/CD pour des applications conteneurisées déployées sur Amazon ECS ou EKS, avec construction et test d'images Docker et déploiement automatisé.
Infrastructure as Code
Déploiement automatisé d'infrastructures définies avec CloudFormation ou Terraform, permettant des mises à jour contrôlées et testées de l'infrastructure.
Déploiements multi-environnements
Gestion automatisée des déploiements à travers différents environnements (dev, test, staging, production) avec des tests et validations appropriés à chaque niveau.
Industries qui utilisent AWS CodePipeline
De nombreux secteurs tirent parti d'AWS CodePipeline pour automatiser leurs processus de livraison de logiciels :