如何在引用密钥库的 arm 模板中为 Web 应用程序设置连接字符串?
How to set a connection string for web app in arm template that references a keyvault?
我正在构建部署 Web 应用程序、sql 数据库和密钥保管库的 arm 模板。
Web 应用程序将与
一起部署
1- 系统身份(将用于访问密钥库)。
2- 将使用 keyvault 访问方式的 sql 数据库的连接字符串:
@Microsoft.KeyVault(SecretUri=https://', parameters('keyVaultName'),'.vault.azure.net/secrets/connectionString)')
密钥库将与
一起部署
1 - 上述网络应用程序的访问策略。
2 - 包含连接字符串的秘密(在部署时在管道中构建)。
webapp 需要在 keyvault 之前部署,所以当部署 keyvault 时,它可以找到 webapp 身份,从而为其创建访问策略。
但我在使用这种方法时遇到的问题是,当连接字符串作为 webapp 的一部分添加时,keyvault 尚不存在,因此 @Microsoft.KeyVault 访问秘密的方式不存在'即使在部署了 keyvault 之后也无法正常工作,我得到以下
但是,如果我删除连接字符串并在部署后手动添加它,并保持完全相同的值,它就可以工作。
如何部署包含 keyvault 访问方式的连接字符串,使 webapp 满意并且可以访问其中的连接字符串?
我认为问题很清楚,不需要包含模板,但如果您确实需要查看,请发表评论并添加到问题中。
编辑
Template
您可以在 keyvault 上使用 depends on condition。我首先创建了一个 Keyvault 并添加了
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('appBaseName'))]"
同时设置访问策略。
所以完整的模板将是:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"appBaseName": {
"type": "string"
},
"sqlName": {
"type": "string"
},
"adminLogin": {
"type": "string"
},
"secretValue": {
"type": "securestring"
},
"adminPassword": {
"type": "securestring"
},
"appInsights": {
"type": "string"
},
"collation": {
"type": "string",
"defaultValue": "Arabic_CI_AS"
},
"edition": {
"type": "string",
"defaultValue": "Basic"
},
"secretsPermissions": {
"type": "array",
"defaultValue": [
"get",
"list"
]
},
"objectiveName": {
"type": "string",
"defaultValue": "Basic"
},
"keyVaultName": {
"type": "string"
}
},
"resources": [
{
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "2019-09-01",
"name": "[parameters('keyVaultName')]",
"location": "[resourceGroup().location]",
"properties": {
"enabledForDeployment": false,
"enabledForDiskEncryption": false,
"enabledForTemplateDeployment": false,
"tenantId": "[subscription().tenantId]",
"accessPolicies": [
{
"objectId": "[reference(concat('Microsoft.Web/sites/', parameters('appBaseName')), '2018-11-01','Full').identity.principalId]",
"tenantId": "[subscription().tenantId]",
"permissions": {
"secrets": "[parameters('secretsPermissions')]"
},
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('appBaseName'))]"
]
}
],
"sku": {
"name": "Standard",
"family": "A"
},
"networkAcls": {
"bypass": "AzureServices",
"defaultAction": "Allow"
}
}
},
{
"type": "Microsoft.KeyVault/vaults/secrets",
"apiVersion": "2019-09-01",
"name": "[concat(parameters('keyVaultName'), '/', 'connectionString')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]"
],
"properties": {
"value": "[parameters('secretValue')]"
}
},
{
"name": "[parameters('appInsights')]",
"type": "microsoft.insights/components",
"location": "[resourceGroup().location]",
"apiVersion": "2020-02-02",
"kind": "web",
"properties": {
"ApplicationId": "[parameters('appInsights')]",
"Application_Type": "web",
"Flow_Type": "Bluefield",
"Request_Source": "rest"
}
},
{
"name": "[parameters('appBaseName')]",
"type": "Microsoft.Web/serverfarms",
"location": "[resourceGroup().location]",
"apiVersion": "2015-08-01",
"sku": {
"name": "F1"
},
"dependsOn": [],
"tags": {
"displayName": "appBaseName"
},
"properties": {
"name": "[parameters('appBaseName')]",
"numberOfWorkers": 1
}
},
{
"name": "[parameters('appBaseName')]",
"type": "Microsoft.Web/sites",
"location": "[resourceGroup().location]",
"apiVersion": "2015-08-01",
"identity": { "type": "SystemAssigned" },
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', parameters('appBaseName'))]",
"[resourceId('microsoft.insights/components', parameters('appInsights'))]"
],
"tags": {
"[concat('hidden-related:', resourceId('Microsoft.Web/serverfarms', parameters('appBaseName')))]": "Resource",
"displayName": "appBaseName"
},
"properties": {
"name": "[parameters('appBaseName')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('appBaseName'))]",
"siteConfig": {
"location": "[resourceGroup().location]",
"appSettings" : [
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(concat('microsoft.insights/components/', parameters('appInsights')), '2015-05-01').InstrumentationKey]"
}],
"connectionStrings": [
{
"name": "connectionString",
"connectionString": "[concat('@Microsoft.KeyVault(SecretUri=https://', parameters('keyVaultName'),'.vault.azure.net/secrets/connectionString)')]",
"type": 1
}
]
}
}
},
{
"name": "[parameters('sqlName')]",
"type": "Microsoft.Sql/servers",
"location": "[resourceGroup().location]",
"apiVersion": "2014-04-01",
"dependsOn": [],
"properties": {
"administratorLogin": "[parameters('adminLogin')]",
"administratorLoginPassword": "[parameters('adminPassword')]"
},
"resources": [
{
"name": "AllowAllWindowsAzureIps",
"type": "firewallRules",
"location": "[resourceGroup().location]",
"apiVersion": "2014-04-01",
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', parameters('sqlName'))]"
],
"properties": {
"startIpAddress": "0.0.0.0",
"endIpAddress": "0.0.0.0"
}
},
{
"name": "[parameters('sqlName')]",
"type": "databases",
"location": "[resourceGroup().location]",
"apiVersion": "2014-04-01",
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', parameters('sqlName'))]"
],
"properties": {
"collation": "[parameters('collation')]",
"edition": "[parameters('edition')]",
"maxSizeBytes": "1073741824",
"requestedServiceObjectiveName": "[parameters('objectiveName')]"
}
}
]
}
],
"outputs": {}
}
输出:
(部署成功)
(Keyvault 引用已正确设置)
(也正确设置了 Vault 访问策略)
我正在构建部署 Web 应用程序、sql 数据库和密钥保管库的 arm 模板。
Web 应用程序将与
一起部署1- 系统身份(将用于访问密钥库)。
2- 将使用 keyvault 访问方式的 sql 数据库的连接字符串:
@Microsoft.KeyVault(SecretUri=https://', parameters('keyVaultName'),'.vault.azure.net/secrets/connectionString)')
密钥库将与
一起部署1 - 上述网络应用程序的访问策略。
2 - 包含连接字符串的秘密(在部署时在管道中构建)。
webapp 需要在 keyvault 之前部署,所以当部署 keyvault 时,它可以找到 webapp 身份,从而为其创建访问策略。
但我在使用这种方法时遇到的问题是,当连接字符串作为 webapp 的一部分添加时,keyvault 尚不存在,因此 @Microsoft.KeyVault 访问秘密的方式不存在'即使在部署了 keyvault 之后也无法正常工作,我得到以下
但是,如果我删除连接字符串并在部署后手动添加它,并保持完全相同的值,它就可以工作。
如何部署包含 keyvault 访问方式的连接字符串,使 webapp 满意并且可以访问其中的连接字符串?
我认为问题很清楚,不需要包含模板,但如果您确实需要查看,请发表评论并添加到问题中。
编辑 Template
您可以在 keyvault 上使用 depends on condition。我首先创建了一个 Keyvault 并添加了
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('appBaseName'))]"
同时设置访问策略。
所以完整的模板将是:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"appBaseName": {
"type": "string"
},
"sqlName": {
"type": "string"
},
"adminLogin": {
"type": "string"
},
"secretValue": {
"type": "securestring"
},
"adminPassword": {
"type": "securestring"
},
"appInsights": {
"type": "string"
},
"collation": {
"type": "string",
"defaultValue": "Arabic_CI_AS"
},
"edition": {
"type": "string",
"defaultValue": "Basic"
},
"secretsPermissions": {
"type": "array",
"defaultValue": [
"get",
"list"
]
},
"objectiveName": {
"type": "string",
"defaultValue": "Basic"
},
"keyVaultName": {
"type": "string"
}
},
"resources": [
{
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "2019-09-01",
"name": "[parameters('keyVaultName')]",
"location": "[resourceGroup().location]",
"properties": {
"enabledForDeployment": false,
"enabledForDiskEncryption": false,
"enabledForTemplateDeployment": false,
"tenantId": "[subscription().tenantId]",
"accessPolicies": [
{
"objectId": "[reference(concat('Microsoft.Web/sites/', parameters('appBaseName')), '2018-11-01','Full').identity.principalId]",
"tenantId": "[subscription().tenantId]",
"permissions": {
"secrets": "[parameters('secretsPermissions')]"
},
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('appBaseName'))]"
]
}
],
"sku": {
"name": "Standard",
"family": "A"
},
"networkAcls": {
"bypass": "AzureServices",
"defaultAction": "Allow"
}
}
},
{
"type": "Microsoft.KeyVault/vaults/secrets",
"apiVersion": "2019-09-01",
"name": "[concat(parameters('keyVaultName'), '/', 'connectionString')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]"
],
"properties": {
"value": "[parameters('secretValue')]"
}
},
{
"name": "[parameters('appInsights')]",
"type": "microsoft.insights/components",
"location": "[resourceGroup().location]",
"apiVersion": "2020-02-02",
"kind": "web",
"properties": {
"ApplicationId": "[parameters('appInsights')]",
"Application_Type": "web",
"Flow_Type": "Bluefield",
"Request_Source": "rest"
}
},
{
"name": "[parameters('appBaseName')]",
"type": "Microsoft.Web/serverfarms",
"location": "[resourceGroup().location]",
"apiVersion": "2015-08-01",
"sku": {
"name": "F1"
},
"dependsOn": [],
"tags": {
"displayName": "appBaseName"
},
"properties": {
"name": "[parameters('appBaseName')]",
"numberOfWorkers": 1
}
},
{
"name": "[parameters('appBaseName')]",
"type": "Microsoft.Web/sites",
"location": "[resourceGroup().location]",
"apiVersion": "2015-08-01",
"identity": { "type": "SystemAssigned" },
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', parameters('appBaseName'))]",
"[resourceId('microsoft.insights/components', parameters('appInsights'))]"
],
"tags": {
"[concat('hidden-related:', resourceId('Microsoft.Web/serverfarms', parameters('appBaseName')))]": "Resource",
"displayName": "appBaseName"
},
"properties": {
"name": "[parameters('appBaseName')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('appBaseName'))]",
"siteConfig": {
"location": "[resourceGroup().location]",
"appSettings" : [
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(concat('microsoft.insights/components/', parameters('appInsights')), '2015-05-01').InstrumentationKey]"
}],
"connectionStrings": [
{
"name": "connectionString",
"connectionString": "[concat('@Microsoft.KeyVault(SecretUri=https://', parameters('keyVaultName'),'.vault.azure.net/secrets/connectionString)')]",
"type": 1
}
]
}
}
},
{
"name": "[parameters('sqlName')]",
"type": "Microsoft.Sql/servers",
"location": "[resourceGroup().location]",
"apiVersion": "2014-04-01",
"dependsOn": [],
"properties": {
"administratorLogin": "[parameters('adminLogin')]",
"administratorLoginPassword": "[parameters('adminPassword')]"
},
"resources": [
{
"name": "AllowAllWindowsAzureIps",
"type": "firewallRules",
"location": "[resourceGroup().location]",
"apiVersion": "2014-04-01",
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', parameters('sqlName'))]"
],
"properties": {
"startIpAddress": "0.0.0.0",
"endIpAddress": "0.0.0.0"
}
},
{
"name": "[parameters('sqlName')]",
"type": "databases",
"location": "[resourceGroup().location]",
"apiVersion": "2014-04-01",
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', parameters('sqlName'))]"
],
"properties": {
"collation": "[parameters('collation')]",
"edition": "[parameters('edition')]",
"maxSizeBytes": "1073741824",
"requestedServiceObjectiveName": "[parameters('objectiveName')]"
}
}
]
}
],
"outputs": {}
}
输出:
(部署成功)
(Keyvault 引用已正确设置)
(也正确设置了 Vault 访问策略)