Blog Ingénierie Comment déployer du code dans des environnements multiples avec GitLab CI
Mise à jour : November 21, 2024
Lecture : 12 min

Comment déployer du code dans des environnements multiples avec GitLab CI

GitLab CI est à la fois puissant et polyvalent. Découvrez les capacités de cet outil à travers plusieurs scénarios d'utilisation.

intro.jpg

Imaginez-vous gestionnaire d’un site d'information. Heureusement, le code de votre projet est déjà hébergé sur GitLab.com et vous utilisez GitLab CI/CD pour vos tests. Maintenant, vous souhaitez connaître toutes les possibilités de déploiement.

Par souci de pertinence, supposons que l'application se compose uniquement de fichiers HTML, sans code côté serveur ni compilation sophistiquée des actifs JS. La plateforme de destination sera également générique, nous utiliserons Amazon S3.

Plutôt que de fournir des extraits de code à copier-coller, nous allons vous partager les principes et les fonctionnalités de GitLab CI, afin que vous puissiez les appliquer dans votre propre pile technologique.

Déroulons donc notre histoire depuis son commencement, où il n'est pas encore question d'intégration continue.

La ligne de départ

Déploiement : un ensemble de fichiers HTML devraient apparaître dans votre bucket S3 (déjà configuré pour héberger un site web statique). Il y a des millions de façons de procéder. Dans notre cas, nous utiliserons la bibliothèque AWS CLI fournie par Amazon.

La commande complète ressemble à ceci :

aws s3 cp ./ s3://yourbucket/ --recursive --exclude "*" --include "*.html"

Le push du code vers le dépôt et le déploiement sont deux processus distincts.

Déploiement manuel

Détail important : la commande nécessite de fournir les variables d'environnement AWS_ACCESS_KEY_ID et AWS_SECRET_ACCESS_KEY. Il vous faudra peut-être aussi spécifier AWS_DEFAULT_REGION.

Essayons d'automatiser cette procédure avec l'intégration continue de GitLab.

Votre premier déploiement automatisé

GitLab CI offre une grande flexibilité dans l'exécution des commandes. Sa configuration s'adapte à vos besoins, reproduisant l'environnement de votre terminal local. Ajoutez votre script dans le fichier .gitlab-ci.yml et effectuez un push de votre code : l’outil d'intégration continue de GitLab déclenche un job et vos commandes sont exécutées.

Précisons maintenant le contexte d'utilisation de cet exemple : il s'agit d'un site de taille modeste, avec une trentaine de visiteurs journaliers, et une seule branche principale de dépôt de code. Commençons par spécifier un job avec la commande précédente dans le fichier .gitlab-ci.yml :

deploy:
  script: aws s3 cp ./ s3://yourbucket/ --recursive --exclude "*" --include "*.html"

Oups, la commande a échoué :

Message d'erreur lors de l'exécution d'un job GitLab.

Il fallait d'abord vérifier l'existence d'un exécutable aws. Pour installer awscli, nous avons besoin de pip, qui est un outil d'installation de paquets Python. Spécifions une image Docker avec Python préinstallé, qui devrait également contenir pip :

deploy:
  image: python:latest
  script:
  - pip install awscli
  - aws s3 cp ./ s3://yourbucket/ --recursive --exclude "*" --include "*.html"

Déploiement automatisé

Vous effectuez un push de votre code sur GitLab, et il est automatiquement déployé par l’outil CI.

L'installation d'awscli rallonge le temps d'exécution du job, mais pour l'instant ce n'est pas un souci. Pour accélérer le processus, cherchez une image Docker avec awscli préinstallé, ou créez une image vous-même.

N’oublions pas les variables d'environnement récupérées depuis la console AWS :

variables:
  AWS_ACCESS_KEY_ID: "AKIAIOSFODNN7EXAMPLE"
  AWS_SECRET_ACCESS_KEY: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
deploy:
  image: python:latest
  script:
  - pip install awscli
  - aws s3 cp ./ s3://yourbucket/ --recursive --exclude "*" --include "*.html"

Cela devrait fonctionner, mais attention : ce n'est jamais une bonne idée de dévoiler des clés secrètes de votre code, même dans un dépôt privé. Remédions donc à cette situation.

Des secrets bien gardés

GitLab dispose d’un endroit spécialement dédié aux variables secrètes : Paramètres > CI/CD > Variables.

Ajouter une variable secrète dans GitLab

Tout ce que vous y mettez se transforme en variables d'environnement. En cochant la case « Masquée », vous masquerez la variable dans les job logs. En cochant la case « Protéger la variable », vous n’exporterez la variable uniquement vers les pipelines s'exécutant sur des branches et des étiquettes protégées.

Seuls les utilisateurs ayant le statut de propriétaire ou de chargé de maintenance sur un projet auront accès à cette section. Nous pourrions supprimer la section variables de notre configuration CI, mais nous allons l'utiliser à d'autres fins.

Savoir spécifier et utiliser des variables non-secrètes

Lorsque votre configuration s'agrandit, il devient pratique de conserver certains paramètres sous formes de variables au début de votre configuration. Le cas présent ne le justifie pas, mais pour les besoins de cette démonstration, nous allons définir le nom du compartiment S3 comme variable :

variables:
  S3_BUCKET_NAME: "yourbucket"
deploy:
  image: python:latest
  script:
  - pip install awscli
  - aws s3 cp ./ s3://$S3_BUCKET_NAME/ --recursive --exclude "*" --include "*.html"

Jusqu'ici, tout va bien :

Compilation GitLab CI sans erreur

Dans notre scénario, la fréquentation du site est en hausse, et vous avez embauché un développeur pour vous aider. Voyons comment le workflow GitLab CI s'adapte au travail en équipe.

Comment utiliser GitLab CI en équipe

Avec deux utilisateurs travaillant dans le même dépôt, il n'est plus pratique d'utiliser la branche principale pour le développement. Vous décidez d'utiliser des branches séparées pour les nouvelles fonctionnalités et les nouveaux articles, et de les fusionner dans la branche principale lorsqu'elles sont prêtes.

Cependant, votre configuration CI actuelle ne prend pas en charge les branches. Chaque push effectué vers GitLab sera déployé sur S3. La solution est simple : il suffit d'ajouter only: main au job deploy.

En plus de ne pas vouloir déployer chaque branche sur l’environnement de production, vous souhaiteriez pouvoir prévisualiser vos modifications depuis les branches de fonctionnalités.

Déploiement de la branche principale de GitLab vers AWS S3

Comment configurer un environnement de test ?

Matteo, votre nouveau développeur, vous propose d'utiliser la fonctionnalité GitLab Pages, idéale pour prévisualiser votre travail en cours. Afin d'héberger des sites web sur GitLab Pages, votre fichier de configuration CI doit répondre à trois règles simples :

  • Le job doit être nommé pages
  • Il doit y avoir une section artifacts avec un dossier public
  • Tout ce que vous souhaitez héberger doit être placé dans le dossier public

Le contenu du dossier public sera hébergé à l'adresse suivante : http://<username>.gitlab.io/<projectname>/

Voici la configuration complète après avoir appliqué l’exemple de configuration pour les sites web en HTML :

variables:
  S3_BUCKET_NAME: "yourbucket"

deploy:
  image: python:latest
  script:
  - pip install awscli
  - aws s3 cp ./ s3://$S3_BUCKET_NAME/ --recursive --exclude "*" --include "*.html"
  only:
  - main

pages:
  image: alpine:latest
  script:
  - mkdir -p ./public
  - cp ./*.html ./public/
  artifacts:
    paths:
    - public
  except:
  - main

Nous avons spécifié deux jobs. L'un d'eux déploie le site web pour vos clients sur S3 (deploy). L'autre (pages) déploie le site web sur GitLab Pages. Nommons-les « Environnement de production » et « Environnement de préproduction ». Toutes les branches seront déployées sur GitLab Pages, à l'exception de la branche principale.

Déploiement différencié des branches dans GitLab Pages et S3.

Introduction aux environnements

GitLab offre la prise en charge de nombreux environnements (dynamiques ou statiques) ; vous devez simplement spécifier l'environnement correspondant pour chaque job de déploiement :

variables:
  S3_BUCKET_NAME: "yourbucket"

deploy to production:
  environment: production
  image: python:latest
  script:
  - pip install awscli
  - aws s3 cp ./ s3://$S3_BUCKET_NAME/ --recursive --exclude "*" --include "*.html"
  only:
  - main

pages:
  image: alpine:latest
  environment: staging
  script:
  - mkdir -p ./public
  - cp ./*.html ./public/
  artifacts:
    paths:
    - public
  except:
  - main

GitLab garde une trace de tous vos déploiements. Ainsi, vous savez toujours ce qui est actuellement déployé sur vos serveurs :

Visualisation des environnements sur GitLab CI/CD.

L'historique complet de vos déploiements sur chacun de vos environnements actuels vous est aussi fourni :

Historique des déploiements GitLab.

Maintenant que tout est automatisé et configuré, de nouveaux défis nous attendent.

Comment dépanner les déploiements ?

Oups ! La branche de fonctionnalités que vous avez poussé sur l'environnement de préproduction vient d'être remplacée par celle de Matteo, qui vient d'effectuer un push de sa propre branche. L'énervement vous gagne, c'est la troisième fois que cela arrive aujourd'hui !

Et si vous utilisiez Slack pour notifier vos déploiements, afin d'éviter ce genre de désagrément ?

Recevez des notifications en utilisant l'application GitLab pour Slack.

Du travail d'équipe à grande échelle

Quelque temps plus tard, et vous voilà à la tête d'un site web très populaire, et d'une équipe de huit personnes. Mais, désormais, les membres de votre équipe perdent un temps précieux à attendre de pouvoir prévisualiser leur travail. Le déploiement de chaque branche en préproduction n'est plus optimal.

File d'attente de branches à examiner en préproduction

Il est temps de perfectionner le système. Vous convenez avec votre équipe de fusionner au préalable chaque changement sur la branche de préproduction. La modification du fichier .gitlab-ci.yml est minime :

except:
- main

est remplacé par

only:
- staging

Dessin de développeurs qui fusionnent leurs changements dans une branche de préproduction avant de les déployer sur S3

Vos collaborateurs doivent fusionner leurs branches de fonctionnalités avant de prévisualiser leur travail en préproduction. Cela nécessite plus de temps et d'efforts, mais tout le monde s'accorde à dire que c'est toujours mieux que d'attendre.

Comment gérer les urgences ?

Il arrive parfois que les choses tournent mal. Quelqu'un a mal fusionné des branches et a effectué un push du résultat directement en production, juste au moment où le hashtag de votre site devenait viral sur les réseaux sociaux. Des milliers de personnes voient des visuels cassés au lieu de votre page d'accueil habituelle. Heureusement, la fonction Restaurer l’environnement a permis de résoudre le problème en moins d'une minute.

Fonctionnalité de restauration sur la plateforme GitLab

La fonction de restauration de l'environnement relance le job précédent avec la validation précédente. Vous avez décidé de désactiver le déploiement automatique en production et de passer au déploiement manuel. Pour ce faire, vous devez ajouter when : manual à votre job. Il n'y aura effectivement plus de déploiement automatique en production. Le déploiement manuel s'effectue en allant dans Compilation > Pipelines, et en cliquant sur « Exécuter des jobs manuels ou différés » :

Déploiement manuel sur GitLab.

Effectuons maintenant un bond en avant dans le temps. Votre entreprise est devenue une société de plusieurs centaines d'employés travaillant sur le site web, et les compromis précédents ne fonctionnent plus.

Faire ses premiers pas avec les Review Apps

Logiquement, la nouvelle étape consiste à lancer une instance temporaire de l'application par branche de fonctionnalités pour la revue. Pour cela, nous avons configuré un autre bucket S3. Sa seule particularité est que le contenu du site est placé dans un dossier portant le nom de la branche de développement, de sorte que l’URL ressemble à :

http://<REVIEW_S3_BUCKET_NAME>.s3-website-us-east-1.amazonaws.com/<branchname>/

Voici le remplacement du job pages utilisé auparavant :

review apps:
  variables:
    S3_BUCKET_NAME: "reviewbucket"
  image: python:latest
  environment: review
  script:
  - pip install awscli
  - mkdir -p ./$CI_BUILD_REF_NAME
  - cp ./*.html ./$CI_BUILD_REF_NAME/
  - aws s3 cp ./ s3://$S3_BUCKET_NAME/ --recursive --exclude "*" --include "*.html"

Ici, il est bon de connaître l'origine de cette variable $CI_BUILD_REF_NAME. GitLab prédéfinit de nombreuses variables d'environnement à utiliser dans vos jobs. Notez que nous avons défini la variable S3_BUCKET_NAME à l'intérieur du job. Vous pouvez ainsi réécrire les définitions de niveau supérieur.

Représentation visuelle de la configuration des Review Apps :

Dessin représentant la configuration Review Apps de GitLab.

Les détails de l'implémentation des Review Apps varient selon votre pile technologique et de votre processus de déploiement. Tout ne sera pas aussi simple qu'avec un site HTML statique. Programmer des instances temporaires à la volée avec tous les logiciels et services requis n'est pas chose aisée. Mais tout cela peut être accompli, notamment à l'aide des conteneurs Docker, Chef ou Ansible.

Le déploiement avec Docker mériterait d'ailleurs un article complet. Et si vous regrettez l'absence de scénarios plus complexes qu'un simple déploiement en HTML statique, nous vous recommandons de lire cet article. Abordons maintenant un dernier sujet.

Déployer sur différentes plateformes

Dans la pratique, nous ne sommes pas limités à S3 et à GitLab Pages. Nous hébergeons et déployons nos applications sur différents services. De plus, si vous décidez un jour de passer à une nouvelle plateforme, vous devrez alors réécrire tous vos scripts de déploiement. Vous pourrez alors utiliser une petite merveille appelée dpl pour vous faciliter la tâche.

Jusqu'ici, nous avons utilisé awscli pour livrer du code à un service comme Amazon S3. Quel que soit le système utilisé, le principe reste le même : vous exécutez une commande avec certains paramètres et transmettez une clé secrète d'authentification. L'outil de déploiement dpl utilise ce principe et fournit une interface unique pour cette liste de fournisseurs. Voici à quoi ressemblerait le déploiement d’un job en production avec dpl:

variables:
  S3_BUCKET_NAME: "yourbucket"

deploy to production:
  environment: production
  image: ruby:latest
  script:
  - gem install dpl
  - dpl --provider=s3 --bucket=$S3_BUCKET_NAME
  only:
  - main

En cas de déploiement sur plusieurs systèmes ou de changements fréquents de plateforme de destination, dpl vous aide à uniformiser vos scripts de déploiement.

Cinq points clés à retenir

  1. Un déploiement est une commande (ou un ensemble de commandes) régulièrement exécutée. Il peut donc être exécuté dans GitLab CI.

  2. La plupart des commandes à exécuter nécessitent de fournir une ou plusieurs clés secrètes, que vous stockez dans Paramètres > CI/CD > Variables.

  3. Avec GitLab CI, vous pouvez spécifier de façon flexible les branches vers lesquelles vous déployez votre code.

  4. GitLab conserve l'historique des déploiements dans tous vos environnements, et vous permet de revenir à n'importe quelle version précédente.

  5. Pour les éléments critiques de votre infrastructure, vous pouvez activer le déploiement manuel depuis l'interface de GitLab, au lieu du déploiement automatisé.

Votre avis nous intéresse

Cet article de blog vous a plu ou vous avez des questions ou des commentaires ? Partagez vos réflexions en créant un nouveau sujet dans le forum de la communauté GitLab. Partager votre expérience

Lancez-vous dès maintenant

Découvrez comment la plateforme DevSecOps unifiée de GitLab peut aider votre équipe.

Commencer un essai gratuit

Découvrez le forfait qui convient le mieux à votre équipe

En savoir plus sur la tarification

Découvrez ce que GitLab peut offrir à votre équipe

Échanger avec un expert