各位工程师大家好!
我试图了解一些如何使用 ARM 模板通过我的自定义域自动部署 Function App。将资源组的初始设置(存储帐户、应用服务计划、日志分析、Key Vault(带有“mycertificate”)、应用程序洞察)放在一边,我只想在这里重点关注 Function App 的部署。
在我的 ARM 模板中,我有以下资源:
"type": "Microsoft.Web/sites"
- 功能应用程序本身"type": "Microsoft.Web/sites/extensions"
- 邮政部署"type": "Microsoft.Web/certificates"
- 将证书部署到应用服务"type": "Microsoft.Web/sites/hostNameBindings"
- 来自 Function App 的证书参考资源在像
4(last) < 3 < 2 < 1(first)
这样的链中设置了“dependsOn”。
现在,如果我使用资源运行 ARM 模板
1,2,3,4
它不起作用。它给了我
“资源‘Microsoft.Web/certificates/mycertificate’下 找不到资源组“ResourceGroupName”。”
但是,如果我使用资源运行 ARM 模板
1,2,3
,它会成功,然后我可以再次运行使用资源的 ARM 模板 1,2,3,4
,然后这个也会成功 => 我已经成功部署了带有证书的 Function App。
虽然我很高兴知道有一些途径可以实现我计划做的事情,但我必须说运行两个部署(使用资源
1,2,3
,然后1,2,3,4
)的必要性相当麻烦。
我希望有人可以解释为什么它有效,并且也许有一些建议如何在没有部署
1,2,3
的中间步骤的情况下做到这一点。
作为参考,这里是资源 3 和 4:
{
"type":"Microsoft.Web/certificates",
"name":"mycertificate",
"apiVersion":"2016-03-01",
"location":"[resourceGroup().location]",
"dependsOn":[...],
"properties":{
"keyVaultId":"[resourceId('Microsoft.KeyVault/vaults', variables('keyVaultName'))]",
"keyVaultSecretName":"mycertificate",
"serverFarmId":"[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]"
}
},
{
"type":"Microsoft.Web/sites/hostNameBindings",
"apiVersion":"2023-01-01",
"name":"myfunction/myfunction.mydomain.com",
"location":"[resourceGroup().location]",
"dependsOn":[
"[resourceId('Microsoft.Web/certificates', 'mycertificate')]"
],
"properties":{
"siteName":"myfunction",
"hostNameType":"Verified",
"sslState":"SniEnabled",
"thumbprint":"[reference(resourceId('Microsoft.Web/certificates', 'mycertificate'), '2019-08-01').Thumbprint]",
"customHostNameDnsRecordType":"CName"
}
}
感谢您的帮助。
我认为您遇到的问题是由于 ARM 模板部署过程中资源创建的时间和依赖关系造成的。
在第一个部署中(资源 1、2、3): 资源 1、2 和 3 已部署。 Function App 已创建,zip 部署完成,证书已部署到 App Service。
在第二个部署中(资源 1、2、3、4): 资源 1、2 和 3 已部署,因此 Azure 可以引用它们。资源 4 (hostNameBindings) 取决于证书(资源 3)。在第二次部署期间,Azure 发现第一次部署时资源 3(证书)已存在,因此它能够将主机名绑定到 Function App。
首先尝试部署您的函数:
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2020-06-01",
"name": "functionAppDeployment",
"properties": {
"mode": "Incremental",
"template": {
"resources": [
{
"type": "Microsoft.Web/sites",
"name": "functionApp",
"apiVersion": "2021-02-01",
"location": "[resourceGroup().location]",
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]"
}
},
{
"type": "Microsoft.Web/sites/extensions",
"name": "functionAppDeploy",
"apiVersion": "2021-02-01",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', 'functionApp')]"
],
"properties": {
"appName": "functionApp",
"slotName": "production",
"version": "1.0",
"type": "zip",
"content": "<zip package content>"
}
}
]
}
}
}
然后做这样的事情:
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2020-06-01",
"name": "certAndHostNameBindingDeployment",
"dependsOn": [
"functionAppDeployment"
],
"properties": {
"mode": "Incremental",
"template": {
"resources": [
{
"type": "Microsoft.Web/certificates",
"name": "mycertificate",
"apiVersion": "2021-02-01",
"location": "[resourceGroup().location]",
"dependsOn": [
"functionAppDeployment"
],
"properties": {
"keyVaultId": "[resourceId('Microsoft.KeyVault/vaults', variables('keyVaultName'))]",
"keyVaultSecretName": "mycertificate",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]"
}
},
{
"type": "Microsoft.Web/sites/hostNameBindings",
"name": "myfunction/myfunction.mydomain.com",
"apiVersion": "2023-01-01",
"location": "[resourceGroup().location]",
"dependsOn": [
"mycertificate"
],
"properties": {
"siteName": "functionApp",
"hostNameType": "Verified",
"sslState": "SniEnabled",
"thumbprint": "[reference(resourceId('Microsoft.Web/certificates', 'mycertificate'), '2021-02-01').thumbprint]",
"customHostNameDnsRecordType": "CName"
}
}
]
}
}
}