如何检查手臂模板中是否存在资源

时间:2019-07-08 09:28:38

标签: azure arm-template

如何通过资源类型和标识符识别ARM模板中的天蓝色资源是否存在

5 个答案:

答案 0 :(得分:9)

实际上是可能的。您可以使用资源组标签来标记当前已部署的版本,如果设置了标签,则可以跳过部署。所有这些都可以通过链接模板来实现。
请注意,我们本身并不检查资源是否存在,但仍然允许编写可能包含一次初始化模板的ARM模板。如果资源组被删除并且资源丢失(如果您再次创建了资源组),则最后一个将还原资源。您可以扩展它以支持每个资源的标签,这在某些情况下会更加有用。

开始部署的模板可能如下所示:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "DeploymentTemplateLink": {
            "type": "string"
        },
        "DeploymentVersion": {
            "defaultValue": 1,
            "type": "int"
        }
    },
    "variables": {
      "rgWithDefaultVersion": {
          "tags": {
             "Version": "0"
          }
      }
    },
    "resources": [
        {
            "type": "Microsoft.Resources/deployments",
            "apiVersion": "2017-05-10",
            "name": "DeploymentTemplate",
            "condition": "[less(int(union(variables('rgWithDefaultVersion'), resourceGroup()).tags['Version']), parameters('DeploymentVersion'))]",
            "properties": {
                "mode": "Incremental",
                "templateLink": {
                    "uri": "[parameters('DeploymentTemplateLink')]",
                    "contentVersion": "1.0.0.0"
                },
                "parameters": {
                    "DeploymentVersion": {
                        "value": "[parameters('DeploymentVersion')]"
                    }
                }
            }
        }
    ]
}

链接的模板的条件会查询标记,并且仅当当前版本(存储在标记中)小于请求的版本时才返回true。实际上,您不必维护版本控制:只需不设置 DeploymentVersion 参数,它将仅在第一次部署。如果仍然决定重新部署,则始终可以选择增加版本,这将导致链接模板的部署(也称为“主部署”)。

主部署模板在您身上,但是它应该包含一个 tags 资源,以维护逻辑。

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "DeploymentVersion": {
            "defaultValue": 1,
            "type": "int"
        }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.Resources/tags",
            "name": "default",
            "apiVersion": "2019-10-01",
            "dependsOn": [],
            "properties": {
                "tags": {
                    "Version": "[string(parameters('DeploymentVersion'))]"
                }
            }
        }
    ]
}

注释,用于那些不了解 union() rgWithDefaultVersion 的人。如果引用的对象不包含属性,则ARM模板部署将失败。在我们的例子中,我们有两个这样的属性:'tags''Version'“标签” 仅在特定资源组具有或曾经具有标签的情况下存在。 “版本” 仅在我们已经编写一次之后(在主部署中)才存在。因此,在访问它们之前,我们使用适当的默认值对返回的对象执行 union()操作,以确保我们可以安全地访问所提到的属性。

答案 1 :(得分:1)

在手臂模板中无法做到这一点。您可以使用一些外部源(例如powershell)来确定并传递具有适当值的参数,或者,您可以使用标签来弄清楚(具有表示资源存在/不存在的标签)。

答案 2 :(得分:0)

资源管理器提供以下用于获取资源值的功能:Resource functions for Azure Resource Manager templates

您可以用一块powershell来包装模板,无论使用哪种方法,它都会确定资源是否存在,并根据该参数传递参数值,并在模板中使用条件语句,该条件语句将根据输入(但是输入必须来自其他地方)

答案 3 :(得分:0)

您可能会发现https://docs.microsoft.com/en-us/azure/developer/terraform/overview对解决您的案件很有帮助。
Hashicorp Terraform是用于置备和管理云基础架构的开源工具。它将基础结构编入描述云资源拓扑的配置文件中。这些资源包括虚拟机,存储帐户和网络接口。 Terraform CLI提供了一种简单的机制来将配置文件部署和版本化到Azure。

但这需要您离开ARM模板。

答案 4 :(得分:-1)

最近我需要一个解决方案来基本上对SQL Server进行增量更新。既然你做不到,模板将失败,并显示NameAlreadyExists错误。 因此,我需要检查资源是否存在,并仅在不存在的情况下创建。

添加“条件”检查,确定天蓝色资源ID是否存在;不要创建它。

{
 ...
 "condition": "[empty(resourceId('[resourceGroup().id]', 'Microsoft.SQL/servers', parameters('serverName')))]",
 ...
}

您可以对任何资源类型执行此操作。