如何在通过链接的 ARM 模板部署的存储帐户上列出密钥?
How to listkeys on a storage account deployed via linked ARM template?
下面我有一个(简化的)Azure ARM 模板来部署一个网站,该网站在其 appSettings 中有存储帐户。我最初通过字符串输出参数传递密钥,效果很好。
存储模板
"outputs": {
"storageKey": {
"type": "string",
"value": "[listKeys(resourceid(resourceGroup().name, 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value]"
}
}
根模板
{
"apiVersion": "[variables('apiVersion')]",
"type": "Microsoft.Resources/deployments",
"name": "[concat(resourceGroup().Name, '-', variables('tdfConfiguration')[copyIndex()]['roleName'], '-storage')]",
"copy": {
"name": "storageCopy",
"count": "[length(variables('tdfConfiguration'))]"
},
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('storageAccountTemplateUri')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"storageAccountName": { "value": "[variables('tdfConfiguration')[copyIndex()]['componentName']]" },
"storageAccountLocation": { "value": "[resourceGroup().location]" },
"storageAccountType": { "value": "[variables('storageAccountType')]" }
}
}
},
{
"apiVersion": "[variables('apiVersion')]",
"type": "Microsoft.Resources/deployments",
"name": "[concat(resourceGroup().Name, '-', variables('tdfConfiguration')[copyIndex()]['roleName'], '-website')]",
"copy": {
"name": "webSiteCopy",
"count": "[length(variables('tdfConfiguration'))]"
},
"dependsOn": [
"[concat('Microsoft.Resources/deployments/', resourceGroup().Name, '-', variables('tdfConfiguration')[copyIndex()]['roleName'], '-serviceplan')]",
"[concat('Microsoft.Resources/deployments/', resourceGroup().Name, '-', variables('tdfConfiguration')[copyIndex()]['roleName'], '-storage')]"
],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('webSiteTemplateUri')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"azureWebJobsStorageAccountKey": { "value": "[reference(concat(resourceGroup().Name, '-', variables('tdfConfiguration')[copyIndex()]['roleName'], '-storage')).outputs.storageKey.value]" }
}
}
},
我担心将其作为字符串传递可能会在某些部署日志中暴露它。但是,如果我将其切换为安全字符串输出参数 。所以看起来我需要在根模板中列出键,但是如果我将我的网站参数更改为
"azureWebJobsStorageAccountKey": { "value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts',variables('tdfConfiguration')[copyIndex()]['componentName']), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value]" }
它失败了,因为即使存储帐户被列为 dependsOn,它也会尝试立即解析此值而不等待部署存储帐户。有什么想法吗?
list*
函数将等待资源可用(如果资源是在同一模板中创建的)。但是您使用的是嵌套模板,因此它无法知道资源是否已配置,因此它只是假设已配置(使用 list*
函数时的标准行为)。
不要将其作为值传递(这真的没有意义),只需在部署中使用相同的表达式即可。因为只有在之前的部署完成并且存储帐户已经存在之后,部署才会开始。
另外,我不明白你为什么要用嵌套模板这样做,我不明白在你的情况下这样做的任何理由,你过度复杂化了你的 deployment\code 没有任何好处(甚至造成了问题因为那个为你自己)。只需删除嵌套部署并使用资源。
下面我有一个(简化的)Azure ARM 模板来部署一个网站,该网站在其 appSettings 中有存储帐户。我最初通过字符串输出参数传递密钥,效果很好。
存储模板
"outputs": {
"storageKey": {
"type": "string",
"value": "[listKeys(resourceid(resourceGroup().name, 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value]"
}
}
根模板
{
"apiVersion": "[variables('apiVersion')]",
"type": "Microsoft.Resources/deployments",
"name": "[concat(resourceGroup().Name, '-', variables('tdfConfiguration')[copyIndex()]['roleName'], '-storage')]",
"copy": {
"name": "storageCopy",
"count": "[length(variables('tdfConfiguration'))]"
},
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('storageAccountTemplateUri')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"storageAccountName": { "value": "[variables('tdfConfiguration')[copyIndex()]['componentName']]" },
"storageAccountLocation": { "value": "[resourceGroup().location]" },
"storageAccountType": { "value": "[variables('storageAccountType')]" }
}
}
},
{
"apiVersion": "[variables('apiVersion')]",
"type": "Microsoft.Resources/deployments",
"name": "[concat(resourceGroup().Name, '-', variables('tdfConfiguration')[copyIndex()]['roleName'], '-website')]",
"copy": {
"name": "webSiteCopy",
"count": "[length(variables('tdfConfiguration'))]"
},
"dependsOn": [
"[concat('Microsoft.Resources/deployments/', resourceGroup().Name, '-', variables('tdfConfiguration')[copyIndex()]['roleName'], '-serviceplan')]",
"[concat('Microsoft.Resources/deployments/', resourceGroup().Name, '-', variables('tdfConfiguration')[copyIndex()]['roleName'], '-storage')]"
],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('webSiteTemplateUri')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"azureWebJobsStorageAccountKey": { "value": "[reference(concat(resourceGroup().Name, '-', variables('tdfConfiguration')[copyIndex()]['roleName'], '-storage')).outputs.storageKey.value]" }
}
}
},
我担心将其作为字符串传递可能会在某些部署日志中暴露它。但是,如果我将其切换为安全字符串输出参数
"azureWebJobsStorageAccountKey": { "value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts',variables('tdfConfiguration')[copyIndex()]['componentName']), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value]" }
它失败了,因为即使存储帐户被列为 dependsOn,它也会尝试立即解析此值而不等待部署存储帐户。有什么想法吗?
list*
函数将等待资源可用(如果资源是在同一模板中创建的)。但是您使用的是嵌套模板,因此它无法知道资源是否已配置,因此它只是假设已配置(使用 list*
函数时的标准行为)。
不要将其作为值传递(这真的没有意义),只需在部署中使用相同的表达式即可。因为只有在之前的部署完成并且存储帐户已经存在之后,部署才会开始。
另外,我不明白你为什么要用嵌套模板这样做,我不明白在你的情况下这样做的任何理由,你过度复杂化了你的 deployment\code 没有任何好处(甚至造成了问题因为那个为你自己)。只需删除嵌套部署并使用资源。