ARM 模板部署:将 reference() 函数用于条件部署时出现 DeploymentNotFound 错误

时间:2021-04-14 19:56:09

标签: azure azure-resource-manager arm-template

我有一个主要的 ARM 模板,我们称之为 azuredeploy.json,还有一个链接模板,我们称之为 privateEndpoint.json。我有一个参数来决定是否部署资源,我们称之为enablePrivateEndpoints。当前设置为“false”,因此不会部署此资源。

在相反的情况下,应读取“privateEndpoint.json”的输出以获取私有端点的 networkInterface id。

azuredeploy.json

{
            "condition": "[not(equals(parameters('enablePrivateEndpoints'), 'false'))]",
            "name": "keyvault-privateendpoint",
            "type": "Microsoft.Resources/deployments",
            "apiVersion": "2019-10-01",
            "dependsOn": [
                "keyvault"
            ],
            "properties": {
                "mode": "Incremental",
                "templateLink": {
                "uri": "[concat(variables('templateFolderUrl'), '/', variables('privateEndpointTemplateFileName'), parameters('_artifactsLocationSasToken'))]"
                },
                "parameters": {
                ...
...
                "enablePrivateEndpoints": "[parameters('enablePrivateEndpoints')]"
                }
            }
        },
},
{
            "condition": "[not(equals(parameters('enablePrivateEndpoints'), 'false'))]",
            "name": "networkInterface-kv",
            "type": "Microsoft.Resources/deployments",
            "apiVersion": "2019-10-01",
            "properties": {
                "mode": "Incremental",
                "templateLink": {
                "uri": "[concat(variables('templateFolderUrl'), '/', variables('networkInterfaceTemplateFileName'), parameters('_artifactsLocationSasToken'))]"
                },
                "parameters": {
                    "networkInterfaceId": {
                        "value": "[reference('keyvault-privateendpoint', '2021-04-01').outputs.networkInterfaceId.value]"
                    }
                }
            }
        }

privateEndpoint.json

...
"enablePrivateEndpoints": {
      "type": "string"
    }
    },
    "variables": {},    
    "resources": [
        {
            "name": "[parameters('privateEndpointName')]",
            "type": "Microsoft.Network/privateEndpoints",
            "apiVersion": "2021-04-01",
            "location": "[resourceGroup().location]",
            "dependsOn": [],
            "properties": "[parameters('privateEndpointProperties')]"
        }
    ],
    "outputs": {
      "networkInterfaceId": {
        "condition": "[not(equals(parameters('enablePrivateEndpoints'), 'false'))]",
        "type": "string",
        "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('privateEndpointName'))).networkInterfaces[0].id]"
      }
    }

问题在于这段代码:

"networkInterfaceId": {
                        "value": "[reference('keyvault-privateendpoint', '2021-04-01').outputs.networkInterfaceId.value]"
                    }

尽管条件停止了引用资源的部署,但仍在评估引用函数。部署失败,出现“DeploymentNotFound:找不到部署‘keyvault-privateendpoint’”

以下是我尝试解决此问题的一些方法:

尝试 #1

您可以看到我已经尝试向输出本身添加条件

"outputs": {
      "networkInterfaceId": {
        "condition": "[not(equals(parameters('enablePrivateEndpoints'), 'false'))]",
        "type": "string",
        "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('privateEndpointName'))).networkInterfaces[0].id]"
      }
    }

这并没有解决问题

尝试#2

我尝试向查看输出本身的值添加一个 if,仅在 enablePrivateEndpoints 参数为真时评估引用函数。

"networkInterfaceId": {
                        "value": "[if(parameters(enablePrivateEndpoints), reference('keyvault-privateendpoint', '2021-04-01').outputs.networkInterfaceId.value, '')]"
                    }

这也没有解决问题。

我不明白为什么仍然试图引用不存在的部署。

我的意思是,即使是进行引用的部署资源本身也是在相同参数下有条件的。

注意:这些资源还没有成功部署,所以它们是新的。

2 个答案:

答案 0 :(得分:1)

尝试使用

"networkInterfaceId": 
{
                    
"value": "[if(not(equals(parameters('enablePrivateEndpoints'), 'false')), reference('keyvault-privateendpoint', '2021-04-01').outputs.networkInterfaceId.value , '')]"
}

在资源 "type": "Microsoft.Resources/deployments" 的参数中。

答案 1 :(得分:0)

我发现了问题所在。使用条件部署时,这并不意味着不会评估引用函数,因为它是一个运行时函数。

如果您不希望在部署时进行评估,则必须在有条件部署中使用引用函数的任何位置添加额外的 if

这包括在输出中。

见下文,链接模板的输出现在有一个 if: privateEndpoint.json

"networkInterfaceId": {
        "condition": "[equals(parameters('enablePrivateEndpoints'), 'true')]",
        "type": "string",
        "value": "[if(equals(parameters('enablePrivateEndpoints'), 'true'), reference(resourceId('Microsoft.Network/privateEndpoints', parameters('privateEndpointName'))).networkInterfaces[0].id, '1')]"

然后在主部署 arm 模板中,引用函数再次放在 if 后面: azuredeploy.json

"networkInterfaceId": {
                        "value": "[if(equals(parameters('enablePrivateEndpoints'), 'true'), reference('keyvault-privateendpoint', '2021-04-01').outputs.networkInterfaceId.value, '1')]"
                    }