[英]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 数据工厂门户中的设置图片:
当我尝试将其导出到 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”覆盖参数中,并且它起作用了! (包括引号!)
我希望这可以帮助您或将来遭受同样挫折/困惑的任何人。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.