Automatiser le déploiement d'une application dans un EC2 AWS CodeDeploy

Introduction

L’automatisation est devenue une pierre angulaire du développement logiciel moderne, permettant aux équipes de se concentrer sur l’innovation plutôt que sur les tâches répétitives. Parmi les nombreuses solutions offertes par Amazon Web Services (AWS), CodeDeploy se distingue comme un outil puissant et flexible pour automatiser le déploiement des applications. Que vous gériez une petite application ou une infrastructure complexe, AWS CodeDeploy simplifie le processus de mise en production, en réduisant les erreurs humaines et en garantissant des déploiements cohérents.

Dans cet article, nous explorerons comment configurer et utiliser AWS CodeDeploy pour automatiser le déploiement d’une application sur une instance EC2. Nous aborderons les concepts clés, les étapes de configuration, et fournirons des exemples pratiques pour vous aider à démarrer rapidement. Que vous soyez un développeur débutant ou un professionnel chevronné, vous trouverez des informations précieuses pour améliorer votre flux de travail et garantir des déploiements réussis.

Configuration d’un EC2 avec l’agent CodeDeploy pour les déploiement

Création d’un Role IAM permettant à l’agent :

Pour que l’agent CodeDeploy puisse fonctionner correctement sur une instance EC2, il doit disposer de certains rôles IAM (Identity and Access Management) qui lui accordent les permissions nécessaires pour interagir avec les services AWS. Pour le déploiement, l’agent devra accéder à un bucket S3 pour la récupération de l’application, manipuler l’instance EC2 et pousser les logs des actions sur CloudWatch. Voici les rôles IAM clés sans être regardant sur les politiques associées dont l’agent CodeDeploy aura besoin :

  • AmazonEC2FullAccess
  • AmazonS3FullAccess
  • AWSCodeDeployFullAccess
  • CloudWatchActionsEC2Access
IAM Role

Association du role IAM à l’instance EC2

A la création de l’EC2, dans la section “Configure Instance Details”, recherchez le champ “IAM role” et dans le menu déroulant “IAM role”, sélectionnez le rôle que vous avez créé.

Pour modifier une instance existance, dans la console, sélectionnez l’instance à laquelle vous souhaitez attacher le rôle IAM. Avec l’instance sélectionnée :

  • cliquez sur “Actions”, puis sur “Security”, et enfin sur “Modify IAM role”.
  • Dans le menu déroulant “IAM role”, sélectionnez le rôle que vous avez créé.
  • Cliquez sur “Update IAM role”.
EC2 Role IAM

Installation de l’agent CodeDeploy dans l’EC2

Pour installer l’agent CodeDeploy sur une instance EC2 en fonction de la région AWS, nous devons télécharger et installer la version appropriée de l’agent CodeDeploy pour cette région. Voici les étapes détaillées pour installer l’agent CodeDeploy en utilisant un script qui détecte automatiquement la région de l’instance EC2 :

#!/bin/bash

# Déterminer la région
REGION=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | grep region | awk -F\" '{print $4}')

# Télécharger l'agent CodeDeploy en fonction de la région
sudo yum update -y
sudo yum install -y ruby wget

# Créer le répertoire temporaire pour le téléchargement
TMP_DIR=/tmp/codedeploy_install
mkdir -p $TMP_DIR
cd $TMP_DIR

# Télécharger l'agent CodeDeploy
wget https://aws-codedeploy-${REGION}.s3.${REGION}.amazonaws.com/latest/install

# Rendre le script d'installation exécutable et l'exécuter
chmod +x ./install
sudo ./install auto

# Vérifier que l'agent CodeDeploy est installé et en cours d'exécution
sudo systemcl status codedeploy-agent

Ce script peut être rajouter au champ UserData pour automatiser l’installation de l’agent lors de la création de l’instance. Il est également à noter qu’il faut changer les commandes d’installation des paquets par apt si l’instance Ec2 est de la famille de Debian.

Création des configurations permettant à l’agent de faire le déploiement

Nous allons partir sur une base de spring-boot à base de java 17 pour cette partie. Vous pouvez retrouver le dépôt Github ici AWS CodeDeploy simplifie le processus de deploiement en utilisant un fichier de configuration appsec.yml pour définir les actions à effectuer à chaque phase du déploiement. Voici notre example de fichier pour le déploiement de notre application spring boot dans un Ec2 de type AMI.

version: 0.0
os: linux
files:
  - source: demo-0.0.1-SNAPSHOT.jar
    destination: /home/ec2-user/server/
    overwrite: true

hooks:
  BeforeInstall:
    - location: stop.sh
      timeout: 300
      runas: root

  AfterInstall:
    - location: install.sh
      timeout: 300
      runas: root
    - location: rename.sh
      timeout: 300
      runas: root

  ApplicationStart:
    - location: start.sh
      timeout: 300
      runas: root

  ValidateService:
    - location: validate.sh
      timeout: 300
      runas: root

La structure du fichier appsec.yml est la suivante :

  • version : La version du fichier de configuration.
  • os : Le système d’exploitation cible pour le déploiement (ici, linux).
  • files : Une liste des fichiers à déployer. Chaque entrée spécifie la source du fichier, la destination sur l’instance cible, et si le fichier doit être écrasé s’il existe déjà.
  • hooks : Les scripts à exécuter à différents stades du déploiement (BeforeInstall, AfterInstall, ApplicationStart, ValidateService). Chaque script a un emplacement, un délai d’expiration (timeout), et l’utilisateur sous lequel il doit être exécuté (runas).

Le déploiement c’est lorsque l’agent codedeploy copie les fichiers de la section files vers leur destination. Dans notre cas :

  • le script stop.sh est exécuté pour arrêter le service systemd avant (BeforeInstall) le copie du fichier demo-0.0.1-SNAPSHOT.jar :
#!/bin/bash
# Stop the Spring Boot application
echo "Stopping Spring Boot application"
if systemctl is-active --quiet server; then
systemctl stop server
else
echo "server.service is not running"
fi
  • Après la copie des fichiers (AfterInstall), le script install.sh est exécuter pour installer java17 puis créer le fichier service systemd permettant de démarrer le service:
#!/bin/bash
# Install Java 17 (OpenJDK)
echo "Installing Java 17 (OpenJDK)"

yum install -y java-17-amazon-corretto.x86_64
# Create a systemd service file for the Spring Boot application
echo "Creating systemd service file"
cat <<EOF > /etc/systemd/system/server.service
[Unit]
Description=My App Server
After=syslog.target

[Service]
User=ec2-user
WorkingDirectory=/home/ec2-user/server
ExecStart=/usr/bin/java -Duser.timezone=UTC -Dserver.port=8080 -jar /home/ec2-user/server/app.jar
SuccessExitStatus=143
StandardOutput=append:/var/log/server/server.log
StandardError=append:/var/log/server/server.log
SyslogIdentifier=my-server

[Install]
WantedBy=multi-user.target
EOF


# Reload systemd to apply the new service
systemctl daemon-reload

# Create a log file for the Spring Boot application
mkdir -p /var/log/server/
touch /var/log/server/server.log
chown ec2-user:ec2-user /var/log/server/server.log
chmod 664 /var/log/server/server.log

Un autre service rename.sh est exécuter pour renommer le ficher demo-0.0.1-SNAPSHOT.jar en app.jar car je n’ai pas reussi à le faire faire par codedeploy lors de la copie.

  • Après la fin de l’installation le script start.sh est exécutée pour démarrer l’application (ApplicationStart) :
#!/bin/bash
# Start the Spring Boot application using systemd
echo "Starting Spring Boot application"
systemctl restart server
systemctl enable server
  • Une fois l’installation terminée le script validate.sh est exécutée pour savoir si l’installation a été faite avec succès afin de décider s’il faut faire un rollback ou pas :
#!/bin/bash
# Validate that the service is running
echo "Validating Spring Boot application"
SERVICE_URL="http://localhost:1080/actuator/health"
STATUS_CODE=$(curl -s -o /dev/null -w "%{http_code}" $SERVICE_URL)
if [ "$STATUS_CODE" -ne 200 ]; then
echo "Service is not running or not healthy"
exit 1
else
echo "Service is running and healthy"
fi

Pour créer un package de déploiement compatible avec AWS CodeDeploy, il faut que les fichiers appsec.yml, les scripts sh ainsi que le fichier demo-0.0.1-SNAPSHOT.jar soit tous dans un dossier avec une structure comme mon dossier deploy dans le dépôt GitHub :

deploy/
├── appspec.yml
├── demo-0.0.1-SNAPSHOT.jar
├── stop.sh
├── install.sh
├── rename.sh
├── start.sh
└── validate.sh

Il faut ensuite zipper le dossier puis le charger dans un bucket S3 (dans notre cas).

cd deploy
zip -r myapp.zip *
S3 package

Création d’une application CodeDeploy et déploiement de l’application

Pour effectuer le déploiement, il faut créer une application dans CodeDeploy dans la console d’Aws.

Application

Il faut ensuite créer un groupe de déploiement (Deployment Groups) qui permet de cibler les instances Ec2(on peut aussi cibler des VMs On-premises, un Auto Scaling Group) dans lesquelles les déploiements se feront. Ce ciblage se fait sur la base de tags (dans mon cas Group=Dev). Il est aussi possible de pousser la configuration plus loin en déterminant les stratégies de déploiement dans les Ec2 (une à la fois, la moité à la fois, tout en même temps) ou utiliser le loadbalancer pour bloquer le traffic vers les instances en cours d’installation.

Deployment Group

Il ne reste plus qu’à créer un déploiement en spécifiant le paquet codedeploy charger sur le bucket S3 puis le groupe de déploiement a les Ec2 cible. Dans l’application (demo-docs-deploy), cliquer sur l’onglet “Create Deployment” et renseigner les champs.

Deployment

En cliquant sur les détails du déploiement créé , on peut voir l’état de chaque étape.

Deployment Events

Toutes les étapes ont réussi dans ma capture, dans le cas d’échec, il est possible de faire un rollback du déploiement . Je peux me connecter dans l’Ec2 et faire mes tests :

Spring Boot

Conclusion

Automatiser le déploiement d’une application avec AWS CodeDeploy représente un véritable atout pour les équipes de développement et d’opérations. En utilisant un fichier de configuration appspec.yml, vous pouvez définir précisément les actions à effectuer à chaque phase du déploiement, assurant ainsi une transition fluide et sans interruption de vos applications.

La création d’un package de déploiement bien structuré et son association avec un rôle IAM approprié permettent de sécuriser et de simplifier le processus de déploiement. Grâce à l’intégration avec S3 et l’automatisation via des scripts, vous pouvez réduire considérablement les erreurs humaines et gagner en efficacité.

En somme, AWS CodeDeploy offre une solution robuste et flexible pour gérer le cycle de vie des applications, de la mise à jour à la maintenance. En maîtrisant les différentes étapes, de la configuration des instances EC2 à la création et au déploiement des packages, vous pouvez garantir des déploiements réussis et une infrastructure agile prête à répondre aux besoins de votre entreprise. Adoptez ces pratiques et voyez vos processus de déploiement évoluer vers plus de fiabilité et de performance.

Sources :

S'inscrire à ma liste de diffusion

Abonnement réussi

Erreur lors de l'inscription.

Nous ne communiquerons jamais votre adresse électronique à qui que ce soit.