Concevoir le pipeline
Dans cette unité, vous allez suivre l’équipe web de Tailspin qui définit son pipeline de mise en production pour le site web Space Game.
Quand vous planifiez un pipeline de mise en production, vous commencez généralement par identifier les phases (c’est-à-dire les divisions principales) de ce pipeline. Chaque phase est généralement associée à un environnement. Par exemple, dans le module précédent, le pipeline de base d’Andy et Mara comportait une phase de déploiement associée à une instance d’Azure App Service.
Dans ce module, vous allez promouvoir les changements d’une phase à l’autre. Dans chaque phase, vous déployez le site web Space Game sur l’environnement associé à la phase.
Après avoir défini les phases dont vous avez besoin, réfléchissez à la façon dont les changements sont promus d’une phase à l’autre. Chaque phase peut définir les critères de réussite qui conditionnent le passage de la build à la phase suivante. Azure Pipelines offre plusieurs méthodes pour contrôler quand et comment les changements sont promus dans le pipeline. Ces approches sont globalement utilisées pour la gestion de versions.
Dans cette section, vous allez :
- Découvrir les différences entre les phases de pipeline courantes telles que la génération, le développement, le test et la préproduction
- Comprendre comment utiliser les déclencheurs de déploiement manuels, planifiés et continus pour contrôler quand un artefact passe à la phase suivante du pipeline.
- Découvrir comment une approbation de mise en production suspend le pipeline jusqu’à ce qu’un approbateur accepte ou refuse la mise en production
La réunion
Toute l’équipe web de Tailspin est réunie. Dans le module Créer un pipeline de mise en production avec Azure Pipelines, l’équipe a planifié ses tâches pour le sprint actuel. Chaque tâche est associée à la création du pipeline de mise en production pour le site web Space Game.
Rappelez-vous que l’équipe a choisi ces cinq tâches pour son sprint :
- Créer un pipeline multiphase
- Connecter l’application web à une base de données.
- Automatiser les tests de qualité.
- Automatiser les tests de performances.
- Augmenter la cadence de mise en production
L’équipe s’est réunie pour parler de la première tâche, Créer un pipeline multiphase. Après avoir défini le pipeline, l’équipe peut passer de sa preuve de concept de base à un pipeline de mise en production comprenant davantage de phases, de contrôles qualité et d’approbations.
Amita et Tim regardent Andy et Mara qui font la démonstration du pipeline de mise en production une deuxième fois. Ils voient que l’artefact est généré et installé sur App Service.
De quelles phases de pipeline avez-vous besoin ?
Quand vous souhaitez implémenter un pipeline de mise en production, il est important de commencer par identifier les phases dont vous avez besoin. Les phases que vous choisissez dépendent de vos exigences. Suivons à présent l’équipe, qui décide des phases nécessaires.
Tim : Très bien. Je comprends l’idée d’un pipeline automatisé. J’apprécie la simplicité du déploiement sur Azure. Mais qu’allons-nous faire à partir de cette démonstration ? Il nous faut quelque chose que nous pouvons réellement utiliser pour nos mises en production.
Amita : Bien ! Nous devons ajouter d’autres phases. Par exemple, nous n’avons actuellement aucun emplacement pour une phase de test.
Tim : Nous avons aussi besoin d’une phase où nous pourrions présenter les nouvelles fonctionnalités à la direction. Je ne peux rien envoyer à la production sans approbation de la direction.
Andy : Bien sûr. Nous avons fait le point sur la fonction d’un pipeline de mise en production. Mais comment faire en sorte que ce pipeline fasse ce dont nous avons besoin ?
Mara : Nous allons réfléchir à nos exigences pour planifier nos prochaines étapes. Voyons ce dont nous disposons déjà.
Mara s’approche du tableau blanc et trace le schéma du pipeline existant.
Mara : La phase de génération génère le code source et produit un package. Dans notre cas, ce package est un fichier .zip. La phase de déploiement installe le fichier .zip, c’est-à-dire le site web Space Game, sur une instance d’App Service. Que manque-t-il à notre pipeline de mise en production ?
Ajouter la phase de développement
Andy : Je suis peut-être un peu influencé, mais je pense que nous avons besoin d’une phase de développement. Je pense même qu’il devrait s’agir de la première phase après la génération de l’artefact. Les développeurs ne peuvent pas toujours exécuter le service entier à partir de leur environnement de développement local. Par exemple, un système de commerce électronique peut nécessiter un site web, une base de données de produits et un système de paiement. Il nous faut une phase qui inclut tout ce dont l’application a besoin.
Dans notre cas, la fonctionnalité de leaderboard du site web Space Game lit les meilleurs scores à partir d’une source externe. Pour le moment, elle lit des scores fictifs à partir d’un fichier. En configurant une phase de développement, nous disposerions d’un environnement dans lequel nous pourrions intégrer l’application web à une vraie base de données. Cette base de données pourra toujours contenir des scores fictifs, mais elle nous rapprochera de notre application finale.
Mara : Bonne idée. Nous n’allons pas encore intégrer l’application à une véritable base de données. Mais dans une phase de développement, nous pouvons effectuer un déploiement dans un environnement où nous pouvons ajouter une base de données.
Mara modifie son schéma sur le tableau blanc. Elle remplace la phase de déploiement par la phase de développement.
Andy : Vous soulevez un point intéressant. Nous générons l’application chaque fois que nous poussons un changement vers GitHub. Cela signifie-t-il que chaque build achevée est promue à la phase de développement ?
Mara : La génération continue nous offre un retour précieux sur l’état de nos builds et de nos tests. Toutefois, nous souhaitons que la promotion vers la phase de développement (Dev) n'intervienne que lorsque nous fusionnons du code dans une branche centrale, à savoir la branche primaire ou une autre branche de mise en production. Je vais modifier le schéma pour représenter cette exigence.
Mara : Je pense que cette promotion sera facile à effectuer. Nous pouvons définir une condition qui fait en sorte que la promotion vers la phase de développement s’effectue uniquement quand des changements se produisent sur une branche de mise en production.
Quelles sont les conditions ?
Dans Azure Pipelines, utilisez une condition pour exécuter une tâche ou un travail en fonction de l’état du pipeline. Vous avez utilisé des conditions dans les modules précédents.
Rappelons certaines conditions que vous pouvez spécifier :
- Seulement quand toutes les tâches dépendantes précédentes ont réussi
- Même si une dépendance précédente a échoué, sauf si l’exécution a été annulée
- Même si une dépendance précédente a échoué, même si l’exécution a été annulée
- Seulement quand une dépendance précédente a échoué
- Quelques conditions personnalisées
Voici un exemple de base :
steps:
- script: echo Hello!
condition: always()
La condition always()
entraîne l’impression de « Hello ! » par cette tâche de façon inconditionnelle, même si les tâches précédentes ont échoué.
Cette condition est utilisée si vous ne spécifiez pas de condition :
condition: succeeded()
La fonction intégrée succeeded()
vérifie si la tâche précédente a réussi. Si la tâche précédente échoue, cette tâche et les tâches suivantes avec la même condition sont ignorées.
Ici, vous voulez créer une condition qui spécifie :
- La tâche précédente a réussi.
- Le nom de la branche Git actuelle est release.
Pour créer cette condition, vous utilisez la fonction intégrée and()
. Cette fonction vérifie si chacune de ses conditions est vraie. Si une condition n’est pas vraie, la condition globale échoue.
Pour récupérer le nom de la branche actuelle, vous utilisez la variable Build.SourceBranchName
intégrée. Vous pouvez accéder aux variables dans une condition de plusieurs façons. Ici, vous utilisez la syntaxe variables[]
.
Pour tester la valeur d’une variable, vous pouvez utiliser la fonction intégrée eq()
. Cette fonction vérifie si ses arguments sont égaux.
En tenant compte de cela, vous appliquez cette condition pour exécuter la phase de développement uniquement quand le nom de la branche actuelle est « release » :
condition: |
and
(
succeeded(),
eq(variables['Build.SourceBranchName'], 'release')
)
La première condition de la fonction and()
vérifie si la tâche précédente a réussi. La seconde condition vérifie si le nom de la branche actuelle est release.
En YAML, vous utilisez la syntaxe |
(barre verticale) pour définir une chaîne qui s’étend sur plusieurs lignes. Vous pouvez définir la condition sur une seule ligne, mais nous l’écrivons de cette façon pour la rendre plus lisible.
Notes
Dans ce module, nous utilisons la branche release (mise en production) comme exemple. Vous pouvez combiner plusieurs conditions pour définir le comportement dont vous avez besoin. Par exemple, vous pouvez créer une condition qui n'exécute la phase que lorsque la build est déclenchée par une demande de tirage (pull request) sur la branche primaire.
Dans la leçon suivante, lorsque vous configurez la phase deDéveloppement, vous utilisez un exemple plus complet.
Pour une description plus complète des conditions dans Azure Pipelines, consultez la documentation sur les expressions.
Mara : Les conditions nous permettent de contrôler quels changements doivent être promus vers quelles phases. Nous pouvons produire un artefact de build pour n’importe quel changement afin de valider notre build et de vérifier qu’elle est saine. Quand nous sommes prêts, nous pouvons fusionner ces changements dans une branche de mise en production et promouvoir cette build vers la phase de développement.
Ajouter la phase de test
Mara : Pour le moment, nous avons les phases de génération et de développement. Quelle prochaine phase allons-nous ajouter ?
Amita : Pouvons-nous ajouter la phase de test à la suite ? Ce serait pour moi la phase idéale pour tester les derniers changements.
Mara ajoute la phase de test à son schéma sur le tableau blanc.
Amita : Ce qui me préoccupe, c’est la fréquence à laquelle je dois tester l’application. Un e-mail m’avertit quand Mara ou Andy effectue un changement. Des changements sont effectués tout au long de la journée et je ne sais jamais quand intervenir. Je pense que j’aimerais voir une build une fois par jour, peut-être quand j’arrive au bureau. Est-ce possible ?
Andy : Bien sûr. Pourquoi ne pas effectuer le déploiement sur l’environnement de test pendant les heures de fermeture ? Nous pourrions par exemple vous envoyer une build tous les matins à 3 h 00.
Mara : Cela me va. Nous pouvons toujours déclencher le processus manuellement si nécessaire. Par exemple, nous pouvons le déclencher si nous avons besoin de vérifier immédiatement un correctif de bogue important.
Mara met à jour son schéma pour montrer le passage de la build de la phase de développement à la phase de test à 3 h 00 chaque matin.
Que sont les déclencheurs ?
Amita : Nous avons à présent compris comment s’effectuent les passages entre phases. Je suis rassurée. Mais comment contrôler le moment auquel s’exécute une phase ?
Mara : Dans Azure Pipelines, nous pouvons utiliser des déclencheurs. Un déclencheur définit le moment auquel s’exécute une phase. Azure Pipelines offre plusieurs types de déclencheurs. Nous avons le choix entre les déclencheurs suivants :
- Déclencheur CI (intégration continue)
- Déclencheur PR (demande de tirage)
- Déclencheur planifié
- Déclencheur d’achèvement de build
Les déclencheurs CI et PR vous permettent de contrôler les branches qui participent au processus global. Par exemple, vous souhaitez générer le projet quand un changement est apporté à une branche, quelle qu’elle soit. Un déclencheur planifié démarre un déploiement à un moment spécifié. Un déclencheur d’achèvement de build exécute une build quand une autre build (par exemple, pour un composant dépendant) s’achève correctement. Il semble que nous ayons besoin d’un déclencheur planifié.
Que sont les déclencheurs planifiés ?
Un déclencheur planifié utilise la syntaxe cron pour faire en sorte qu’une build s’exécute selon une planification définie.
Sur les systèmes Unix et Linux, cron est un moyen courant de planifier l’exécution de travaux selon un intervalle de temps défini ou à un moment donné. Dans Azure Pipelines, les déclencheurs planifiés utilisent la syntaxe cron pour définir le moment auquel s’exécute une phase.
Une expression cron comprend des champs qui correspondent à certains paramètres de temps, à savoir :
mm HH DD MM DW
\ \ \ \ \__ Days of week
\ \ \ \____ Months
\ \ \______ Days
\ \________ Hours
\__________ Minutes
Par exemple, cette expression cron signifie « 3 h 00 chaque jour » : 0 3 * * *
Une expression cron peut inclure des caractères spéciaux pour spécifier une liste ou une plage de valeurs. Dans cet exemple, l’astérisque (*) correspond à n’importe quelle valeur pour les champs Days, Months et Days of week.
En d’autres termes, cette expression cron est lue comme suit :
- À la minute 0,
- À la troisième heure,
- N’importe quel jour du mois,
- N’importe quel mois,
- N’importe quel jour de la semaine,
- Exécuter le travail
Pour spécifier 3 h 00 uniquement du lundi au vendredi, vous utilisez cette expression : 0 3 * * 1-5
Notes
Les planifications cron utilisent le fuseau horaire UTC (temps universel coordonné). Ainsi, dans cet exemple, 3 A.M. fait référence à 3 h 00 au format UTC. Dans la pratique, vous devrez peut-être ajuster l’heure de votre planification cron par rapport à l’heure UTC pour que le pipeline s’exécute à l’heure prévue pour vous et votre équipe.
Pour configurer un déclencheur planifié dans Azure Pipelines, vous avez besoin d’une section schedules
dans votre fichier YAML. Voici un exemple :
schedules:
- cron: '0 3 * * *'
displayName: 'Deploy every day at 3 A.M.'
branches:
include:
- release
always: false
Dans cette section schedules
:
cron
spécifie l’expression cron.branches
spécifie que le déploiement doit être effectué uniquement à partir de la brancherelease
.always
spécifie si le déploiement doit être exécuté de manière inconditionnelle (true
) ou uniquement si des changements ont été apportés à la brancherelease
depuis la dernière exécution (false
). Dans le cas présent, vous spécifiezfalse
, car le déploiement doit être effectué uniquement si des changements ont été apportés à la brancherelease
depuis la dernière exécution.
L’intégralité du pipeline s’exécute quand Azure Pipelines exécute un déclencheur planifié. Le pipeline s’exécute également dans d’autres conditions, par exemple quand vous poussez un changement vers GitHub. Pour exécuter une phase uniquement en réponse à un déclencheur planifié, vous pouvez utiliser une condition qui vérifie si le motif de build est une exécution planifiée.
Voici un exemple :
- stage: 'Test'
displayName: 'Deploy to the Test environment'
condition: and(succeeded(), eq(variables['Build.Reason'], 'Schedule'))
La phase Test
s’exécute uniquement si la phase précédente a réussi et que la variable de pipeline intégrée Build.Reason
est Schedule
.
Vous allez consulter un exemple plus complet plus loin dans ce module.
Amita : Cela me convient très bien. Je n’ai même pas besoin de sélectionner la mise en production manuellement et de l’installer. C’est prêt pour moi.
Andy : Et n’oubliez pas que nous pourrons automatiser cela plus tard si nous le souhaitons. Rien n’est définitif. Le pipeline évolue à mesure que nous apprenons et que nous progressons.
Ajouter la phase de préproduction
Tim : À mon tour. J’ai besoin d’une phase pour exécuter davantage de tests de contrainte. Nous avons également besoin d’une phase de démonstration nous permettant d’obtenir l’approbation de la direction. Pour le moment, nous pouvons combiner ces deux exigences dans une phase que nous pouvons appeler préproduction.
Andy : Bonne idée, Tim. Il est important d’avoir un environnement de préproduction. C’est souvent la dernière étape avant qu’une fonctionnalité ou un correctif de bogue ne soit mis à la disposition de nos utilisateurs.
Mara ajoute la phase de préproduction (Staging) à son schéma sur le tableau blanc.
Amita : Nous utilisons un déclencheur planifié pour promouvoir les changements de la phase de développement à la phase de test. Mais comment faisons-nous la promotion des modifications de la phase de test à la phase de préproduction ? Cette promotion doit-elle également avoir lieu selon une planification ?
Mara : Je pense que la meilleure façon de gérer cela serait une approbation de mise en production. Une approbation de mise en production vous permet de promouvoir manuellement un changement d’une phase à la suivante.
Amita : J’ai l’impression que c’est exactement ce qu’il me faut ! Une approbation de mise en production me donnerait le temps de tester les derniers changements avant de présenter la build à la direction. Je pourrais alors promouvoir la build quand je suis prête.
Mara modifie son schéma pour montrer que la build passe de la phase de test à la phase de préproduction uniquement quand elle est approuvée par Amita.
Tim : J’imagine que nous pourrions également utiliser les approbations de mise en production pour effectuer la promotion de la préproduction à la production après approbation de la direction. Je ne peux jamais prévoir le temps que cela prendra. Après leur approbation, je peux moi-même approuver la mise en production et la promouvoir manuellement en production. Mais comment fonctionnent les approbations de mise en production ?
Que sont les approbations de mise en production ?
Une approbation de mise en production offre un moyen de suspendre le pipeline jusqu’à ce qu’un approbateur accepte ou refuse la mise en production. Pour définir votre workflow de mise en production, vous pouvez combiner des approbations, des conditions et des déclencheurs.
Souvenez-vous que dans le module Créer un pipeline de mise en production avec Azure Pipelines, vous avez défini un environnement dans la configuration de votre pipeline pour représenter votre environnement de déploiement. Voici un exemple avec votre pipeline existant :
- stage: 'Deploy'
displayName: 'Deploy the web application'
dependsOn: Build
jobs:
- deployment: Deploy
pool:
vmImage: 'ubuntu-20.04'
environment: dev
variables:
- group: Release
Votre environnement peut inclure des critères spécifiques pour votre mise en production. Ces critères peuvent spécifier les pipelines pouvant effectuer des déploiements sur cet environnement et les approbations humaines nécessaires pour promouvoir la mise en production d’une phase à la suivante.
Plus loin dans ce module, vous allez définir l’environnement de préproduction et vous attribuer un rôle d’approbateur pour promouvoir l’application web Space Game de la phase de test à la préproduction.
L’automatisation à l’échelle souhaitée
Azure Pipelines vous apporte la flexibilité nécessaire pour automatiser certaines phases tout en contrôlant manuellement celles qui ne sont pas prêtes pour l’automatisation.
Tim : Il est vraiment intéressant de pouvoir définir les critères de promotion des changements d’une phase à l’autre. Mais nous avons défini quelques critères manuels dans notre pipeline. Je pensais que le DevOps consistait à tout automatiser.
Mara : Vous soulevez un point intéressant. Le DevOps consiste effectivement à automatiser les tâches répétitives et sujettes aux erreurs. Cependant, une intervention humaine est parfois nécessaire. Par exemple, nous obtenons l’approbation de la direction avant de mettre en production de nouvelles fonctionnalités. Quand nous aurons acquis de l’expérience avec nos déploiements automatisés, nous pourrons automatiser davantage de tâches manuelles pour accélérer le processus. Par exemple, nous pouvons davantage automatiser des contrôles qualité à la phase de test pour éviter à Amita d’avoir à approuver chaque build.
Tim : Ça a l’air super. Poursuivons avec ce plan pour l’instant. Nous verrons comment accélérer le système plus tard.
Amita : Puisque l’on parle de notre plan, pouvons-nous résumer les étapes suivantes ?
Le plan
Examinons le plan de l’équipe Tailspin, qui s’apprête à passer aux étapes suivantes.
Mara : Voici le pipeline de mise en production que nous souhaitons créer.
Mara montre du doigt le tableau blanc.
Mara : Pour résumer, nos étapes sont les suivantes :
- Générer un artefact de build chaque fois que nous poussons un changement vers GitHub. Il s’agit de la phase de génération.
- Promouvoir l’artefact de build vers la phase de développement. Cette étape s’effectue automatiquement quand la phase de génération réussit et que le changement est effectué dans la branche de mise en production.
- Promouvez l’artefact de build à l’étape de Test chaque matin à 3 h 00. Nous utilisons un déclencheur planifié pour promouvoir automatiquement l’artefact de build.
- Promouvoir l’artefact de build en préproduction une fois la build testée et approuvée par Amita. Nous utilisons une approbation de mise en production pour promouvoir l’artefact de build.
Après approbation de la build par la direction, nous pouvons déployer l’artefact de build sur un environnement de production.
Amita : Cela va-t-il être difficile ? Le travail semble considérable.
Mara : Je ne le trouve pas si grave. Toutes les phases sont bien indépendantes l’une de l’autre. Chaque phase est distincte et comprend son propre ensemble de tâches. Par exemple, ce qui se passe à la phase de test reste à la phase de test.
Chaque phase de déploiement de notre pipeline possède également son propre environnement. Par exemple, quand nous déployons l’application sur l’environnement de développement ou de test, l’environnement est une instance d’App Service.
Enfin, nous testons une seule mise en production à la fois. Nous ne modifions jamais les mises en production au milieu du pipeline. Nous utilisons la même mise en production aux phases de développement et de préproduction, et chacune a son propre numéro de version. Si la mise en production échoue à l’une des phases, nous la corrigeons et la regénérons avec un nouveau numéro de version. Cette nouvelle mise en production suit alors l’ensemble du pipeline depuis le début.
Quelques mots sur la qualité
Vous venez de voir l’équipe concevoir un pipeline qui va entièrement être suivi par l’application, de la génération à la préproduction. Le but de ce pipeline n’est pas uniquement de simplifier le travail de l’équipe. Il vise également à garantir la qualité des logiciels qu’elle livre aux clients.
Comment mesurer la qualité de votre processus de mise en production ? La qualité de votre processus de mise en production ne peut pas être mesurée directement. Ce que vous pouvez mesurer, c’est la performance de votre processus. Si vous modifiez constamment le processus, cela peut indiquer qu’il existe un problème. Quand des mises en production échouent régulièrement au même point du pipeline, cela peut également indiquer un problème avec le processus de mise en production.
Les mises en production échouent-elles toujours à une heure ou un jour spécifique ? Échouent-elles systématiquement après un déploiement sur un environnement particulier ? Recherchez ce type de modèles pour voir si certains aspects du processus de mise en production sont liés ou dépendent les uns des autres.
Un bon moyen de surveiller la qualité de votre processus de mise en production consiste à créer des visualisations de la qualité des mises en production. Par exemple, ajoutez un widget de tableau de bord qui indique l’état de chaque mise en production.
Quand vous voulez mesurer la qualité d’une mise en production spécifique, vous pouvez effectuer tout type de vérification dans le pipeline. Par exemple, vous pouvez exécuter différents types de test comme des tests de charge et d’interface utilisateur tout en exécutant votre pipeline.
Une barrière qualité offre également un excellent moyen de vérifier la qualité de votre mise en production. Il existe de nombreuses barrières qualité différentes. Celles portant sur les éléments de travail, par exemple, permettent de vérifier la qualité de votre processus de spécification. Vous pouvez également ajouter davantage de vérifications de conformité et de sécurité. Par exemple, respectez-vous le principe de double vérification ? Votre traçabilité est-elle appropriée ?
À mesure que vous progressez dans ce parcours d’apprentissage, vous voyez certaines de ces techniques mises en pratique.
Enfin, quand vous concevez un processus de mise en production de qualité, réfléchissez au type de documentation ou de notes de publication à fournir à l’utilisateur. Il peut être difficile de garder votre documentation à jour. Vous pouvez pour cela utiliser un outil comme Azure DevOps Release Notes Generator. Ce générateur est une application de fonction qui contient une fonction déclenchée par HTTP. Il crée un fichier Markdown quand une nouvelle mise en production est créée dans Azure DevOps à l’aide du Stockage Blob Azure.