Index des articles

Volet 1 :

  • La modularisation & packaging de code Python
  • L’intégration sur Azure

Volet 2 (A & B) :

  • L’installation du package depuis Artifacts (A)
  • Déploiement manuel d’une function app utilisant le package (A)
  • Pipeline CI CD pour une function app utilisant le package (B)

Volet 3 :

  • L’intégration continue avec le testing
  • La génération de documentation automatisée

Contenu

Ce second volet sur le packaging de code Python dans un environnement Azure se concentrera sur l’intégration du package dans le cas d’une Function App, déployée sur une Azure Function.

La partie A couvrait la partie dev : l’installation en local et le déploiement manuel de la function app avec le package
La partie B couvrira la partie prod : la création de pipelines CICD pour déployer la function app en continu, avec le package utilisé pour le développement.

Contexte

Un package Python a été mis à disposition par un membre de votre équipe sur Azure Artifacts et vous est donc accessible. Maintenant que vous savez installer ce package dans votre environnement de développement et même le déployer à la main sur une Azure Function, il est temps de créer les pipelines pour automatiser tout ça.

Je ne couvrirai pas dans ce tutoriel la création du repo et l’archivage du code, je pars directement du repo contenant le code et vous renvoie vers la documentation de MS ainsi qu’à cet article qui résume tout le nécessaire.
Le repo contient le code de la partie A, au sein d’un projet de function app en Python.

Notre objectif est le suivant : quand je mets à jour la branche master, un premier pipeline s’occupe de récolter le code présent dans le repo, télécharger les dépendances, y compris notre package et zip le tout ; une fois le zip prêt, un second pipeline le récupère et le déploie sur notre Azure Function.

C’est parti, on peut ouvrir Azure DevOps section Pipelines/ Pipelines et créer un nouveau pipeline de build.

On choisit le « classic editor » afin de faciliter le développement.

Sélectionnez votre projet ainsi que le repo concerné par le pipeline.

Partons d’une feuille blanche, l’objectif ici est de comprendre le processus. Donc on va cliquer sur « Start with an Empty job ».

Les pipelines sont exécutés par des agents d’Azure (par défaut) et on peut choisir sur quelle distribution on veut l’exécuter. Il est possible d’utiliser différents agents en parallèle au sein d’un pipeline et donc d’avoir des travaux exécutés sur différents OS.

Ici je choisis que mes agents seront par défaut sur Ubuntu 18.04, je ne change pas la pool d’agent car mon organisation ne dispose pas de machines configurées pour exécuter des pipelines Azure DevOps, on laisse donc Azure s’en charger.

Je laisse également par défaut les configurations du job 1 et notamment le fait qu’il doit tourner sur l’agent défini par le pipeline.

On va ajouter 5 tâches à ce job :

  • Use Python Version
  • Download package
  • Bash
  • Archive Files
  • Publish build artifacts

Voilà ce que vous devriez avoir. Il est maintenant temps de configurer ces tâches pour avoir un zip rempli et fonctionnel.

1 – Changez la version de Python en 3.6 (ou celle avec laquelle vous travaillez).

2 – Cherchez votre package dans le feed de votre organisation, pensez à regarder dans les versions « Local » ou « Pre release » si vous ne le trouvez pas. Soyez attentif au dossier de destination, que vous choisissez, on en a besoin pour l’étape suivante.

3 – Pour le script, choisissez l’option « inline » et insérez-y le code suivant :

# Fetching wheel file name based on the .whl extension
name="$(ls $(System.ArtifactsDirectory)| grep .whl)"

# Installing packages 
pip3 install --target "./.python_packages/lib/python3.6/site-packages" $(System.ArtifactsDirectory)/$name
pip3 install --target "./.python_packages/lib/python3.6/site-packages" -r requirements.txt

# Removing installation file
rm $(System.ArtifactsDirectory)/$name

La première ligne est moins complexe qu’elle n’en a l’air : elle récupère le nom existe du fichier en .whl contenu dans le dossier où on a téléchargé le package. Comme le nom de ce fichier est déterminé par la version, l’usage de cette commande nous évite de mettre à jour le pipeline à chaque release du package. Ensuite on installe les packages et on retire le fichier wheel du package custom.

Notez qu’ici, j’installe séparément les packages listés dans requirements.txt de mon package custom. Cela implique que ce dernier ne soit pas listé dans le requirements.txt.

Attention, le chemin cible dépend de la version de Python que vous utilisez et le pattern change à partir de la version 3.7 (cf. partie A)

Il est maintenant temps de zipper notre artefact.

Rien de particulier, je zippe ici la totalité des fichiers, puisque mon repo ne contient que la function.

Enfin, je récupère le chemin où l’on a mis notre zip pour le publier dans la dernière tâche.

On peut ensuite aller dans « Triggers » et activer l’intégration continue, qui va déclencher ce pipeline à chaque fois que la branche master du repo « dummy-function » subit une modification.

Vous pouvez désormais Save & queue. Cela créera l’artefact, prêt à être publié.

On touche au but, il n’y a plus qu’à créer le pipeline de release, qui sera bien plus simple que le premier.

Rendez-vous dans Pipelines / Releases et créez un nouveau pipeline.

Utilisez le preset « Deploy a function app to Azure Functions ».

La première étape est d’aller chercher l’artefact que nous avons produit avec le pipeline de build.
On clique donc sur « Add an artifact ».

En sélectionnant le pipeline de build, on remarque qu’il détecte bien l’artefact que nous avons créé.

On passe maintenant à la seule tâche de notre pipeline en cliquant ici.

Dans cette dernière étape, si vous n’en n’avez pas déjà, créez une connexion du repo DevOps à votre souscription Azure. Choisissez  « Function App on Linux » et votre function.

Enfin, retour à l’écran de la release, vous pouvez activer le déploiement continu, ce qui aura pour effet de lancer ce pipeline dès qu’un nouvel artefact est disponible, soit à la suite du pipeline précédent.

Choisissez « Enabled » sous « Continous Deployment Trigger ».

Sauvegardez, et lancez votre première release !

Je vous remercie d’avoir lu ce second article sur l’industrialisation du déploiement de function app, avec un package maison et vous donne rendez-vous pour le 3ème et dernier article de cette série sur le test unitaire et la documentation auto, afin de rendre accessible votre code et d’en garantir la non-régression, release après release.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.