3
votes

Paramétrer les connexions dans Azure Data Factory (modèles ARM)

J'essaie de configurer une Azure Data Factory dans une configuration CI / CD. J'ai suivi les meilleures pratiques de Microsoft ( https://docs.microsoft.com/en-us/azure/data-factory/continuous-integration-deployment ).

J'ai 4 environnements (dev, test, UAT, PRD)

Bref ce que j'ai fait:

  • Créer une fabrique de données Azure et la lier à mon référentiel Azure DevOps sur l'environnement DEV

  • Créez une fabrique de données Azure sur les autres environnements (test, UAT et PRD), mais ne la liez PAS à DevOps. Au lieu de cela, les pipelines sont publiés sur ces fabriques de données à l'aide de modèles ARM et de pipelines de publication dans Azure DevOps.

  • J'ai paramétré toutes les pièces nécessaires pour pouvoir écraser les paramètres dans chacun de mes environnements.

En ce moment, je suis en mesure de déployer avec succès dans mes autres environnements, cependant, le service lié à ma base de données sur Azure ne fonctionne pas. J'ai tout paramétré, comme le suggère Microsoft, mais lorsque j'exporte mon service lié vers un modèle ARM, il utilise une chaîne de connexion au lieu de mes paramètres paramétrés.

Vous trouverez ci-dessous une image de mes paramètres dans le portail Azure Data Factory:configuration daf

Lorsque j'essaye d'exporter ceci vers des modèles ARM, j'obtiens ce qui suit:

{
            "name": "[concat(parameters('factoryName'), '/database')]",
            "type": "Microsoft.DataFactory/factories/linkedServices",
            "apiVersion": "2018-06-01",
            "properties": {
                "parameters": {
                    "sqlServerUrl": {
                        "type": "string"
                    },
                    "databaseName": {
                        "type": "string"
                    },
                    "sqlPwd": {
                        "type": "string"
                    },
                    "sqlAdminUsername": {
                        "type": "string"
                    }
                },
                "annotations": [],
                "type": "AzureSqlDatabase",
                "typeProperties": {
                    "connectionString": {
                        "type": "SecureString",
                        "value": "[parameters('database_connectionString')]"
                    }
                }
            },
            "dependsOn": []
        },

Le problème avec ces modèles ARM est qu'il n'utilise pas les paramètres pour créer la chaîne de connexion, mais il utilise le paramètre de chaîne de connexion database_connectionString (la chaîne de connexion est toujours paramétrée par défaut par Azure, je ne peux donc pas supprimer ce paramètre).

Lorsque le pipeline de version utilise ce modèle, la chaîne de connexion n'est pas renseignée (seuls les paramètres sont renseignés) et, par conséquent, la connexion à la base de données échoue. Comment devez-vous configurer la connexion afin de pouvoir déployer automatiquement (sans interaction humaine) dans tous les environnements en ne modifiant que les paramètres?

Je ne souhaite pas modifier les modèles ARM provenant d'Azure Data Factory, car cela nécessite une interaction humaine


0 commentaires

3 Réponses :


0
votes

Pour ce faire, j'utilise la tâche de Azure resource group deployment dans la version. L'une des options est Override template parameters ce qui vous permettra de faire exactement ce dont vous avez besoin. Vous pouvez créer une liste de paramètres séparés par des espaces pour remplacer votre modèle ARM et passer une variable

Dans votre cas, ce serait

-database_connectionstring $(VariableHere)

Je stockerais la chaîne de connexion dans Azure KeyVault et la lierais à un groupe de variables sécurisées. Vous pouvez également simplement appuyer sur le cadenas sur une variable standard pour la sécuriser.

Ensuite, liez votre variable personnalisée à chaque étape de votre version

Tâche entrez la description de l'image ici

Passer outre entrez la description de l'image ici


1 commentaires

notez que si vous avez des espaces dans votre VariableHere , alors faites ceci "$(VariableHere)"



1
votes

L'une des autres réponses fournies est un moyen valide d'utiliser des paramètres de remplacement. Cette réponse fournira une réponse différente ainsi que des informations supplémentaires sur la manière de définir les connexions SQL et sur l'utilisation et la mise en œuvre de certaines des mises à jour effectuées avec Key Vault et l'intégration de Data Factory.

Si vous utilisez une connexion sur site à SQL, la chaîne de connexion ressemblera à ceci:

"accessPolicies": [
          {
            "tenantID": "[subscription().tenantId]",
            "objectId": "[reference(resourceId('Microsoft.DataFactory/factories/', parameters('DataFactoryName')), '2018-02-01', 'Full').identity.principalId]",
            "permissions": {
              "secrets": [
                "get"
              ],
              "keys": [
                "get"
              ],
              "certificates": [
                "import"
              ]
            },
            "dependsOn": [
              "[resourceId('Microsoft.DataFactory/factories/', parameters('DataFactoryName'))]"
            ]
          }
        ]

Les guillemets sont obligatoires et peuvent être transmis en tant que paramètre de remplacement.

Si vous utilisez une base de données Azure ou même si vous utilisez Key Vault, cherchez à ajouter une identité gérée que Data Factory prend en charge en l'incluant dans votre modèle ARM

    DECLARE @rolename AS NVARCHAR(100) = 'DataFactory_User'
    DECLARE @username AS NVARCHAR(100) -- This will be the DataFactory name
    SET @username = 'DataFacotryName'

if exists(select * from sys.database_principals where name = @username and Type = 'X' or Type='E')
    BEGIN
        DECLARE @dropUserSql varchar(1000)
        SET @dropUserSql='DROP USER [' + @username + ']'
        PRINT 'Executing ' + @dropUserSql
        EXEC (@dropUserSql)
        PRINT 'Completed ' + @dropUserSql
    END

DECLARE @createUserSql varchar(1000)
SET @createUserSql='CREATE USER [' + @username + '] FROM EXTERNAL PROVIDER'
PRINT 'Executing ' + @createUserSql
EXEC (@createUserSql)
PRINT 'Completed ' + @createUserSql

Une fois cela ajouté, la base de données Azure SQL devra avoir l' identité gérée ajoutée . Cela peut être fait via un script SQL réutilisable comme:

 "identity": {
        "type": "SystemAssigned"
    }

Je recommande de supprimer et de recréer cet utilisateur. SQL reconnaît l'empreinte numérique de l'identité gérée et chaque fois que DataFactory est supprimé et recréé, une nouvelle empreinte numérique est créée.

En termes de valorisation de Key Vault, il existe un type LinkedService de Key Vault qui s'appuie sur l'identité gérée décrite ci-dessus pour récupérer les secrets.

Le Key Vault, s'il est déployé via ARM, devra avoir la politique d'accès mise à jour à quelque chose de similaire à ceci:

"Server={serverName};Database={databaseName};User ID={domain}\{userName};Password={password};Integrated Security=True;" 

Cet extrait de code suppose que Key Vault et Data Factory se trouvent dans le même modèle ARM. S'ils ne le sont pas, la stratégie d'accès peut toujours être effectuée via ARM en obtenant l'ObjectId de l'identité gérée définie par Data Factory et en le transmettant en tant qu'ObjectId et en supprimant l'instruction dependOn.


0 commentaires

0
votes

Juste au cas où vous n'auriez pas trouvé de réponse ou résolu ceci:

J'étais dans une situation très similaire, j'avais plusieurs bases de données Azure SQL qui étaient paramétrées (nom de la base de données) et j'avais besoin de changer le nom du serveur SQL dans mon ADF Azure Release Pipeline pour permuter entre les environnements.

J'ai trouvé qu'en inspectant la définition de code du service lié ({} à côté de lui), vous pouvez obtenir une chaîne de connexion qui inclut tous les paramètres que vous avez définis:

Affichage du code de service lié

Paramètre de chaîne de connexion

J'ai copié la valeur de "connectionString" et modifié ce dont j'avais besoin (adresse du serveur) et laissé les paramètres en place, et je l'ai ajouté au paramètre de remplacement "connectionString" dans mon Azure Release Pipeline, et cela a fonctionné! (incluez les citations!)

J'espère que cela vous aidera, vous ou quiconque souffrira à l'avenir de la même frustration / confusion.


0 commentaires