解决无效模板错误
本文说明如何解决无效模板错误。
症状
部署模板时将收到一个指示以下内容的错误:
Code=InvalidTemplate
Message=<varies>
错误消息取决于错误的类型。
原因
此错误可由多种不同类型的错误导致。 它们通常涉及模板中的语法或结构错误。
解决方案 1 - 语法错误
如果有错误消息指出模板验证失败,则可能是模板中存在语法问题。
Code=InvalidTemplate
Message=Deployment template validation failed
此错误很容易发生,因为模板表达式可能很复杂。 例如,存储帐户的以下名称分配具有一组方括号、三个函数、三组圆括号、一组单引号和一个属性:
"name": "[concat('storage', uniqueString(resourceGroup().id))]",
如果未提供匹配的语法,该模板会生成一个不同于所需的值。
收到此类错误时,请仔细检查表达式语法。 考虑使用 Visual Studio 或 Visual Studio Code 等 JSON 编辑器,此类编辑器在出现语法错误时可以发出警告。
解决方案 2 - 段长度不正确
当资源名称的格式不正确时,会发生另一种模板无效错误。
Code=InvalidTemplate
Message=Deployment template validation failed: 'The template resource {resource-name}'
for type {resource-type} has incorrect segment lengths.
根级别的资源其名称中的段必须比资源类型中的段少一个。 段之间用斜杠隔开。 在下面的示例中,类型有两个段,名称有一个段,因此为有效名称。
{
"type": "Microsoft.Web/serverfarms",
"name": "myHostingPlanName",
...
}
但下一个示例 不是有效名称 ,因为其段数与类型的段数相同。
{
"type": "Microsoft.Web/serverfarms",
"name": "appPlan/myHostingPlanName",
...
}
对于子资源来说,类型和名称的段数必须相同。 之所以必须这样,是因为子资源的完整名称和类型包含父名称和类型。 因此,完整名称的段仍比完整类型的段少一个。
"resources": [
{
"type": "Microsoft.KeyVault/vaults",
"name": "contosokeyvault",
...
"resources": [
{
"type": "secrets",
"name": "appPassword",
...
}
]
}
]
确保段数正确对于 Resource Manager 类型来说可能很困难,这些类型应用到各个资源提供程序。 例如,对网站应用资源锁需要使用包含四个段的类型。 因此,该名称包含三个段:
{
"type": "Microsoft.Web/sites/providers/locks",
"name": "[concat(variables('siteName'),'/Microsoft.Authorization/MySiteLock')]",
...
}
解决方案 3 - 参数无效
如果你提供的参数值不是允许值之一,则会收到类似于以下错误的消息:
Code=InvalidTemplate;
Message=Deployment template validation failed: 'The provided value {parameter value}
for the template parameter {parameter name} is not valid. The parameter value is not
part of the allowed values
请仔细检查模板中的允许值,并提供在部署过程中提供这些值之一。 有关允许参数值的详细信息,请参阅 Azure 资源管理器模板的参数部分。
解决方案 4 - 太多目标资源组
你可能在之前的部署中看到此错误,原因是你被限制为一个部署使用 5 个目标资源组。 在 2020 年 5 月,此限额被上调到了 800 个资源组。 有关详细信息,将 Azure 资源部署到多个订阅或资源组。
解决方案 5 - 检测到循环依赖项
当资源以某种方式互相依赖,导致部署无法启动时,就会出现此错误。 将多个相互依赖的项组合在一起时,会导致两个或两个以上的资源等待其他资源,而后者也在进行等待。 例如,resource1 依赖于 resource3,resource2 依赖于 resource1,resource3 依赖于 resource2。 通常情况下,删除不必要的依赖项即可解决此问题。
解决循环依赖项问题的步骤:
- 在模板中找到循环依赖项中标识的资源。
- 检查该资源的 dependsOn 属性并使用 reference 函数查看其所依赖的资源。
- 检查这些资源,看其依赖于哪些资源。 顺着这些依赖项检查下去,直到找到依赖于原始资源的资源。
- 对于循环依赖项所牵涉的资源,请仔细检查所有使用 dependsOn 属性的情况,确定不需要的依赖项。 删除这些依赖项。 如果不确定某个依赖项是否必需,可尝试删除它。
- 重新部署模板。
部署模板时,删除 dependsOn 属性中的值可能导致错误。 如果遇到错误,可将依赖项添加回模板。
如果该方法无法解决循环依赖项问题,可考虑将部分部署逻辑移至子资源(例如扩展或配置设置)中。 将这些子资源配置为在循环依赖项所牵涉的资源之后部署。 例如,假设要部署两个虚拟机,但必须在每个虚拟机上设置引用另一虚拟机的属性。 可以按下述顺序部署这两个虚拟机:
- vm1
- vm2
- vm1 上的扩展依赖于 vm1 和 vm2。 扩展在 vm1 上设置的值是从 vm2 获取的。
- vm2 上的扩展依赖于 vm1 和 vm2。 扩展在 vm2 上设置的值是从 vm1 获取的。
同一方法适用于应用服务应用。 可以考虑将配置值移到应用资源的子资源中。 可以按下述顺序部署两个 Web 应用:
- webapp1
- webapp2
- webapp1 的配置依赖于 webapp1 和 webapp2。 它包含应用设置,其值来自 webapp2。
- webapp2 的配置依赖于 webapp1 和 webapp2。 它包含应用设置,其值来自 webapp1。