解决无效模板错误

本文介绍如何解决 Bicep 文件和 Azure 资源管理器模板(ARM 模板)的模板无效错误。 出现此错误有多种原因,如语法错误、参数值无效或循环依赖。

症状

部署模板时收到错误,其中指出:

Code=InvalidTemplate
Message=<varies>

错误消息取决于错误的类型。

原因

此错误可由多种不同类型的错误导致。 它们通常涉及模板中的语法或结构错误。

解决方案 1:语法错误

如果有错误消息指出模板验证失败,则可能是模板中存在语法问题。

Code=InvalidTemplate
Message=Deployment template validation failed

发生语法错误的可能原因是模板表达式包含许多元素。 例如,存储帐户的名称分配包含成对的单引号或双引号、大括号、方括号和圆括号。 表达式还包含函数,以及美元符号、逗号和句点之类的字符。

name: 'storage${uniqueString(resourceGroup().id)}'

收到此类错误时,请检查表达式的语法。 若要识别模板错误,可以使用包含最新 Bicep 扩展Azure 资源管理器工具扩展Visual Studio Code

解决方案 2:段长度不正确

当资源名称的格式不正确时,会发生另一种模板无效错误。 若要解决该错误,请参阅解决名称和类型不匹配错误

解决方案 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

在模板中检查参数的允许值,并在部署期间使用允许的值。 有关详细信息,请参阅 BicepARM 模板的允许值。

解决方案 4:目标资源组太多

你可能在之前的部署中看到此错误,原因是你被限制为一个部署使用 5 个目标资源组。 在 2020 年 5 月,此限额被上调到了 800 个资源组。 有关详细信息,请参阅如何为 BicepARM 模板部署到多个资源组。

解决方案 5:检测到循环依赖

当资源以某种方式互相依赖,导致部署无法启动时,就会出现此错误。 将多个相互依赖的项组合在一起时,会导致两个或两个以上的资源等待其他资源,而后者也在进行等待。 例如,resource1 依赖于 resource3resource2 依赖于 resource1,以及 resource3 依赖于 resource2。 通常情况下,删除不必要的依赖项即可解决此问题。

当一个资源使用另一个资源的符号名称时,Bicep 将创建隐式依赖项。 使用 dependsOn 的显式依赖项通常是不必要的。 有关详细信息,请参阅 Bicep 依赖项

解决循环依赖项问题的步骤:

  1. 在模板中找到循环依赖项中标识的资源。
  2. 对于该资源,请检查 dependsOn 属性以及 referenceresourceId 函数的任何使用情况,以查看该资源所依赖的资源。
  3. 检查这些资源,看其依赖于哪些资源。 顺着这些依赖项检查下去,直到找到依赖于原始资源的资源。
  4. 对于循环依赖项所牵涉的资源,请仔细检查 dependsOn 属性的所有使用情况,以识别不需要的任何依赖项。 若要排查部署问题,请删除循环依赖关系。 无需删除代码,而是使用注释,让代码不在下一部署期间运行。 可以在 ARM 模板Bicep 文件中使用单行注释 (//) 或多行注释 (/* ... */)。
  5. 重新部署模板。

部署模板时,删除 dependsOn 属性中的值可能会导致错误。 如果遇到错误,可将依赖项添加回模板。 如果使用注释绕过模板中的代码,则可以删除注释以还原代码。

如果该方法无法解决循环依赖项问题,可考虑将部分部署逻辑移至子资源(例如扩展或配置设置)中。 将这些子资源配置为在循环依赖项所牵涉的资源之后部署。 例如,假设要部署两个虚拟机,但必须在每个虚拟机上设置引用另一虚拟机的属性。 可以按下述顺序部署这两个虚拟机:

  1. vm1
  2. vm2
  3. vm1 上的扩展依赖于 vm1 和 vm2。 扩展在 vm1 上设置的值是从 vm2 获取的。
  4. vm2 上的扩展依赖于 vm1 和 vm2。 扩展在 vm2 上设置的值是从 vm1 获取的。

同一方法适用于应用服务应用。 可以考虑将配置值移到应用资源的子资源中。 可以按下述顺序部署两个 Web 应用:

  1. webapp1
  2. webapp2
  3. webapp1 的配置依赖于 webapp1 和 webapp2。 它包含应用设置,其值来自 webapp2。
  4. webapp2 的配置依赖于 webapp1 和 webapp2。 它包含应用设置,其值来自 webapp1。