在Azure数据工厂中参数化连接(ARM模板)
我正在尝试在CI/CD设置中设置Azure数据工厂。我遵循了微软的最佳实践() 我有4个环境(开发、测试、UAT、PRD) 简言之,我所做的是:在Azure数据工厂中参数化连接(ARM模板),azure,azure-resource-manager,azure-data-factory,Azure,Azure Resource Manager,Azure Data Factory,我正在尝试在CI/CD设置中设置Azure数据工厂。我遵循了微软的最佳实践() 我有4个环境(开发、测试、UAT、PRD) 简言之,我所做的是: 创建Azure数据工厂并将其链接到开发环境上的my Azure DevOps repo 在其他环境(测试、UAT和PRD)上创建Azure数据工厂,但不要将其链接到DevOps。相反,使用ARM模板在这些数据工厂上发布管道,并在Azure DevOps中发布管道 我已经参数化了所有必要的部分,以便能够覆盖我的每个环境中的设置 目前,我能够成功地部署
- 创建Azure数据工厂并将其链接到开发环境上的my Azure DevOps repo
- 在其他环境(测试、UAT和PRD)上创建Azure数据工厂,但不要将其链接到DevOps。相反,使用ARM模板在这些数据工厂上发布管道,并在Azure DevOps中发布管道
- 我已经参数化了所有必要的部分,以便能够覆盖我的每个环境中的设置
{
"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参数化,因此我无法删除此参数)
当发布管道使用此模板时,不会填充connectionstring(只填充参数),因此与数据库的连接失败。如何设置连接,以便只需更改参数即可自动(无需人工交互)部署到所有环境
我不想更改来自Azure Data Factory的ARM模板,因为这需要人工交互我通过使用版本中的
Azure资源组部署
任务来做到这一点。其中一个选项是覆盖模板参数,这将允许您准确地执行所需操作。可以创建以空格分隔的参数列表,以替代手臂模板并传入变量
在你的情况下是这样的
-database_connectionstring $(VariableHere)
我会将连接字符串存储在Azure KeyVault中,并将其链接到安全变量组。您也可以点击标准变量上的挂锁来保护它
然后将自定义变量绑定到发行版中的每个阶段
任务
覆盖
提供的另一个答案是使用覆盖参数的有效方法。此答案将提供一个不同的答案,并提供更多关于如何定义SQL连接以及如何利用和实施关键Vault和Data Factory集成的一些更新的上下文 如果使用on-prem连接到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识别托管标识的指纹,每次删除并重新创建数据工厂时,都会创建一个新的指纹
就利用密钥保险库而言,有一个依赖于上述托管身份来检索机密的数据库
如果通过ARM部署密钥库,则需要将访问策略更新为类似以下内容:
"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'))]"
]
}
]
此代码段假定密钥Vault和数据工厂位于同一ARM模板中。如果不是,访问策略仍然可以通过ARM完成,方法是将其作为ObjectId传入并删除dependsOn语句。以防您没有找到答案或解决此问题: 我的情况非常相似,我有几个参数化的Azure SQL数据库(数据库名称),需要在我的ADF Azure发布管道中更改SQL server名称以在环境之间交换 我发现,通过检查链接服务({}旁边)的代码定义,可以得到一个连接字符串,其中包含您定义的任何参数: 我复制了“connectionString”的值,修改了我需要的内容(服务器地址),并保留了参数,并将其添加到Azure发布管道中的“connectionString”覆盖参数中,结果成功了!(包括引号!)
我希望这能帮助您或将来遭受同样挫折/困惑的任何人。请注意,如果您的
VariableHere
中有空格,请执行此“$(VariableHere)”