繁体   English   中英

参数化 Azure 数据工厂中的连接(ARM 模板)

[英]Parameterize connections in Azure data factory (ARM templates)

我正在尝试在 CI/CD 设置中设置 Azure 数据工厂。 我遵循了 Microsoft 的最佳实践( https://docs.microsoft.com/en-us/azure/data-factory/continuous-integration-deployment )。

我有 4 个环境(开发、测试、UAT、PRD)

简而言之,我做了什么:

  • 创建一个 Azure 数据工厂并将其链接到我在 DEV 环境中的 Azure DevOps 存储库

  • 在其他环境(测试、UAT 和 PRD)上创建 Azure 数据工厂,但不要将其链接到 DevOps。 而是使用 ARM 模板在这些数据工厂上发布管道,并在 Azure DevOps 中发布管道。

  • 我已经参数化了所有必要的部分,以便能够覆盖我每个环境中的设置。

此时,我能够成功部署到我的其他环境,但是,我在 azure 上的数据库的链接服务无法正常工作。 我已经参数化了一切,就像微软建议的那样,但是当我将我的链接服务导出到 ARM 模板时,它使用连接字符串而不是我的参数化设置。

下面是我在 Azure 数据工厂门户中的设置图片:daf 设置

当我尝试将其导出到 ARM 模板时,我得到以下信息:

{
            "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": []
        },

这个ARM模板的问题在于它没有使用参数来创建连接字符串,而是使用连接字符串参数database_connectionString(默认情况下连接字符串总是由Azure参数化,所以我不能删除这个参数)。

发布管道使用此模板时,没有填写连接字符串(仅填写参数),因此与数据库的连接失败。 您应该如何设置连接,以便您只需更改参数即可自动(无需人工交互)部署到所有环境?

我不想更改来自 Azure 数据工厂的 ARM 模板,因为这需要人工交互

提供的其他答案之一是使用覆盖参数的有效方法。 此答案将提供不同的答案以及有关如何定义 SQL 连接以及如何利用和实施通过 Key Vault 和数据工厂集成所做的一些更新的更多上下文。

如果使用本地连接到 SQL,则连接字符串将如下所示:

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

引号是必需的,可以作为覆盖参数传入。

如果使用 Azure 数据库甚至使用 Key Vault,请通过将其包含在 ARM 模板中来添加数据工厂支持托管标识

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

添加后,Azure SQL 数据库将需要添加托管标识 这可以通过可重用的 SQL 脚本来完成,例如:

    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

我建议删除并重新创建此用户。 SQL 识别托管标识的指纹,每次删除并重新创建 DataFactory 时,都会创建一个新的指纹。

在利用 Key Vault 方面,有一种 Key Vault 的LinkedService 类型,它依赖于上述托管标识来检索机密。

如果通过 ARM 部署,Key Vault 需要将访问策略更新为类似于以下内容:

"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'))]"
            ]
          }
        ]

此代码段假定 Key Vault 和数据工厂位于同一个 ARM 模板中。 如果它们不是,访问策略仍然可以通过 ARM 实现,方法是获取数据工厂定义的托管标识的 ObjectId 并将其作为 ObjectId 传入并删除dependsOn 语句。

以防万一你还没有找到答案或解决这个问题:

我处于非常相似的情况,我有几个参数化的 Azure SQL 数据库(数据库名称),需要更改 ADF Azure Release Pipeline 中的 SQL 服务器名称以在环境之间交换。

我发现通过检查链接服务的代码定义(它旁边的 {}),您可以获得一个连接字符串,其中包含您定义的任何参数:

链接服务代码视图

连接字符串参数

我复制了“connectionString”的值并修改了我需要的内容(服务器地址)并保留了参数,并将其添加到我的 Azure Release Pipeline 中的“connectionString”覆盖参数中,并且它起作用了! (包括引号!)

我希望这可以帮助您或将来遭受同样挫折/困惑的任何人。

我通过使用 Release 中的Azure resource group deployment任务来执行此操作。 选项之一是Override template parameters ,这将允许您完全按照您的需要进行操作。 您可以创建一个空格分隔的参数列表来覆盖您的 ARM 模板并传入一个变量

在你的情况下,它会是

-database_connectionstring $(VariableHere)

我会将连接字符串存储在 Azure KeyVault 中并将其链接到安全变量组。 您也可以在标准变量上打上挂锁来保护它。

然后将自定义变量绑定到 Release 中的每个 Stage

任务在此处输入图片说明

覆盖在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM