Déploiement automatique pour Azure Data Factory avec Azure DevOps

Publié par Middleway
Catégorie : Azure / Azure Data Factory / DevOps Non classé
24/05/2021

Déployer et variabiliser une Azure Data Factory (ADF) sur différents environnements en exportant son template ARM peut vite devenir fastidieux. D’autant plus quand le nombre de flux à exporter augmente. On a potentiellement des centaines de pipelines et de datasets qui rendent vite les ARMs complexes, difficilement lisibles et manipulables.

A l’inverse, il est possible de tout automatiser ou presque, pour gérer plusieurs ADFs dans divers environnements sans avoir à manipuler aucun template ARM. A la fin de cet article, un simple pipeline de déploiement sur Azure DevOps sera suffisant pour gérer la mise à jour et le déploiement de vos ADFs depuis l’environnement de développement jusqu’à celui de production.

Prérequis

  • Au moins deux Azure Data Factory déjà existantes : une pour le développement et une pour la recette par exemple. On cherche à pouvoir mettre à jour la seconde lorsque l’on a développé de nouveaux flux sur la première.
  • Au moins un keyvault, idéalement un par environnement, i.e. un par Data Factory.
  • Un compte sur Azure DevOps qui a les droits de déployer sur la souscription Azure cible.

Initialiser GIT sur votre ADF de développement

La première chose à faire est de connecter l’ADF de développement à GIT. Pour cela sélectionnez l’ADF concerné dans le portail Azure, puis sélectionnez « Author & Monitor ».

Open Data Factory

L’interface de l’ADF s’ouvre, dans l’onglet « Author » cliquez sur le menu déroulant « Data Factory », puis sur « Set up code repository ».

Set up code repository

Il faut ensuite associer notre ADF à un GIT disponible sur Azure DevOps. Vous pouvez choisir de créer un nouveau répertoire ou d’en utiliser un existant. Dans tous les cas, on note qu’ADF utilisera deux branches différentes, master et adf_publish dans cet exemple. La première contiendra les ARMs à jour, avec un fichier par pipeline, dataset, data flow… La seconde génèrera un ARM complet de l’ADF et de tous ses composants déjà variabilisés ! C’est de cette branche dont on va se servir pour déployer en automatique nos ADFs.

Configure repository

A noter : vous pouvez travailler sur d’autres branches, mais seul le code publié depuis la branche master sera déployé sur l’ADF de développement et sera automatiquement généré dans la branche adf_publish.

Plus précisément, lorsque vous travaillez sur la branche master, chaque nouvelle sauvegarde sera stockée sur GIT, mais seules les publications entraîneront la génération d’un nouvel ARM complet de l’ADF sur adf_publish.

Save or publish

Si ce template est automatiquement variabilisé, il est possible de contrôler plus finement la façon dont il l’est. Dans cet article, on va utiliser la variabilisation par défaut. Mais sachez que si vous le désirez, vous pouvez modifier la génération en allant dans l’onglet « Manage », puis « ARM template », puis « Edit parameter configuration ». Plus d’information ici.

Modify export

Autoriser ADF à accéder à un Key vault

Par la suite, on va se servir de secrets contenus dans des keyvaults pour automatiser au maximum l’intégration continue puis le déploiement de nos ADFs. Pour cela, il est nécessaire d’autoriser les ADFs à accéder aux keyvault dont elles ont besoin.

Vous pouvez autoriser manuellement un ADF à accéder à un keyvault. Pour cela, depuis l’interface du keyvault, sélectionnez « Access policies », puis « Add Access Policy ». Dans « Secret permissions » cochez Get et List. Puis en cliquant sur select principal, une liste déroulante s’ouvre, retrouvez votre ADF et ajoutez la nouvelle policy. Maintenant, votre ADF peut accéder aux secrets stockés dans le keyvault !

Add access policy

Toutefois dans une démarche de déploiement continue, le mieux est de scripter les droits d’accès aux keyvaults pour vos ADFs. Pour cela, on peut ajouter le code suivant au template ARM du keyvault dans le bloc « accessPolicies » :

"accessPolicies": [
          {
            "tenantId": "[subscription().tenantid]",
            "objectId": "[parameters('adf_object_id')]",
            "permissions": {
              "keys": [],							],
              "secrets": [
                "Get",
                "List"
              ],
              "certificates": []
            }
          }
] 

“[parameters(‘adf_object_id’)]” correspond à l’object id de votre ADF, vous pouvez le retrouver dans le volet « Properties » d’un ADF, au niveau de « Managed Identity Object ID ». On le déclare en tant que paramètre de l’ARM pour essayer de réutiliser au maximum nos ARMs de keyvaults sur nos les différents environnements.

Managed identity object id

Créer ses pipelines sur ADF

Pour profiter au maximum de la génération automatique des ARMs de notre ADF de développement, on va utiliser une démarche simple : toujours passer par une URL ou un secret pour paramétrer un dataset. En effet, ceux-ci sont variabilisés par défaut lors de la génération des ARMs.

Avant cela, on va créer le linked service qui nous permettra d’accéder au keyvault. Dans le menu de votre ADF, suivez « Manage », puis « Linked Service » et enfin « + New ».

New linked service

Sélectionnez ensuite « Azure Key Vault ».

Azure Key Vault

Choisissez le nom de votre linked service, puis entrez l’URL du keyvault cible (pour qu’il soit paramétré). Vous pouvez le trouver dans l’onglet « Overview » correspondant au keyvault sous « Vault URI ». Il n’y a rien d’autre à faire, puisqu’on a déjà autorisé notre ADF à accéder aux secrets du keyvault.

Key Vault linked service

Ensuite lorsqu’on créé ses datasets, on peut passer par ce linked service. Voici deux exemples, pour une Azure Function et un Azure Blob Storage :

Azure Function

Dans ce cas-là, on utilise à la fois une URL, et un secret contenant la function app key. Les deux seront variabilisés.

Azure function data set

Azure Blob Storage

Dans ce cas-là, on utilise simplement la chaîne de connexion correspondant au Blob Storage, que l’on stocke dans le keyvault.

Blob Storage Data Set

Encore une fois, il est possible de changer le template de génération des ARMs, si par exemple vous ne souhaitez pas passer par un keyvault. Mais cela peut être fastidieux et demandera des changements à chaque nouveau pipeline, data set ou data flow… Je conseille donc de ne le faire qu’en dernier recourt.

Pipeline de déploiement

Maintenant que notre ADF source est lié à un répertoire GIT, que notre keyvault est alimenté des divers secrets nécessaires et que nos data sets sont correctement paramétrés, il ne nous reste plus qu’à exploiter les templates ARMs auto-générés dans un pipeline de déploiement :

Pipeline de déploiement

La première et la dernière tâche sont optionnelles, elles ne sont utiles que si votre ADF contient des triggers. Auquel cas, il faut les désactiver puis les réactiver après le déploiement. Dans les deux cas, on utilise une tâche Azure Powershell avec les scripts suivants (ADF_name correspond au nom de l’ADF et ResourceGroupName au nom de son ressource group) :

Stop ADF Triggers

$triggersADF = Get-AzDataFactoryV2Trigger -DataFactoryName $(ADF_name) -ResourceGroupName $(ResourceGroupName)

$triggersADF | ForEach-Object { Stop-AzDataFactoryV2Trigger -ResourceGroupName $(ResourceGroupName) -DataFactoryName $(ADF_name)  -Name $_.name -Force }

Start ADF Triggers

$triggersADF = Get-AzDataFactoryV2Trigger -DataFactoryName $(ADF_name) -ResourceGroupName $(ResourceGroupName)

$triggersADF | ForEach-Object { Start-AzDataFactoryV2Trigger -ResourceGroupName $(ResourceGroupName) -DataFactoryName $(ADF_name) -Name $_.name -Force }

La tâche restante exploite les ARMs auto-générés qui sont disponibles sur la branche adf_publish (par défaut), sous le dossier qui porte le nom de votre ADF de développement. Vous y trouvez deux fichiers : ARMTemplateForFactory.json et ARMTemplateParametersForFactory.json, respectivement le template ARM et ses paramètres.

Repo files

Il ne nous reste plus qu’à variabiliser les paramètres de ces fichiers, à savoir : le nom de l’ADF et les URLs. Si vous utilisez un keyvault par environnement, vous n’avez pas besoin de variabiliser les noms des secrets, sinon pensez à le faire (ils sont déjà considérés comme des paramètres de l’ARM). Le tour est joué ! Il ne reste plus qu’à dupliquer ce pipeline de déploiement pour chaque environnement.