你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

解决“找不到资源”错误

本文介绍操作过程中找不到资源时会看到的错误。 通常,此错误出现在使用 Bicep 文件或 Azure 资源管理器模板(ARM 模板)部署资源时。 在执行管理任务且 Azure 资源管理器找不到所需资源时,也会显示此错误。 例如,如果尝试将标记添加到不存在的资源,就会收到此错误。

症状

存在两个错误代码,指示找不到资源。 NotFound 错误返回如下所示的结果:

Code=NotFound;
Message=Cannot find ServerFarm with name exampleplan.

ResourceNotFound 错误返回如下所示的结果:

Code=ResourceNotFound;
Message=The Resource 'Microsoft.Storage/storageAccounts/{storage name}' under resource
group {resource group name} was not found.

原因

资源管理器需要检索资源的属性,但找不到订阅中的资源。

解决方案 1:检查资源属性

如果在执行管理任务时收到此错误,请检查为资源提供的值。 要检查的三个值为:

  • 资源名称
  • 资源组名称
  • 订阅

如果使用的是 PowerShell 或 Azure CLI,请检查是否在包含该资源的订阅中运行了该命令。 可使用 Set-AzContextaz account set 来更改订阅。 许多命令提供了一个订阅参数,使用该参数可以指定与当前上下文不同的订阅。

如果无法验证属性,请登录到 Microsoft Azure 门户。 找到要尝试使用的资源,并检查资源名称、资源组和订阅。

解决方案 2:设置依赖项

如果在部署模板时遇到此错误,可能需要添加依赖项。 如果可能,资源管理器会通过并行创建资源来优化部署。

例如,在部署 Web 应用时,应用服务计划必须存在。 如果未指定该 Web 应用与应用服务计划的依赖关系,则 Resource Manager 会同时创建这两个资源。 Web 应用失败,并出现由于应用服务计划资源尚不存在,因此找不到该资源的错误。 通过在 Web 应用中设置依赖关系可避免此错误。

使用隐式依赖关系而不要使用 resourceId 函数。 该依赖关系是使用资源的符号名称和 ID 属性创建的。

例如,Web 应用的 serverFarmId 属性使用 servicePlan.id 创建对应用服务计划的依赖关系。

resource webApp 'Microsoft.Web/sites@2022-03-01' = {
  properties: {
    serverFarmId: servicePlan.id
  }
}

resource servicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
  name: hostingPlanName
  ...

对于大多数部署,不必要使用 dependsOn 创建显式依赖关系

避免设置不必要的依赖关系。 不必要的依赖关系会延长部署持续时间,因为资源不是并行部署的。 此外,还可能会创建障碍部署的循环依赖关系。

部署顺序

看到依赖项问题时,需要深入了解资源部署顺序。 可以使用门户查看部署操作的顺序:

  1. 登录门户

  2. 在资源组的“概述”中,选择部署历史记录的链接。

    Azure 门户的屏幕截图,其中突出显示了“概览”部分中,指向资源组的部署历史记录的链接。

  3. 对于你要查看的“部署名称”,选择“相关事件”。

    Azure 门户的屏幕截图,其中显示了部署名称,并在部署历史记录中突出显示了相关事件链接。

  4. 检查每项资源的事件的顺序。 请注意每个操作的状态及其时间戳。 例如,下图显示了并行部署的三个存储帐户。 请注意,这三个存储帐户部署同时启动。

    Azure 门户活动日志的屏幕截图,其中平行显示了部署的三个存储帐户,并显示了相应时间戳和状态。

    下图显示了非并行部署的三个存储帐户。 第二个存储帐户依赖于第一个存储帐户,第三个存储帐户又依赖于第二个存储帐户。 第一个存储帐户需要标为“已启动”、“已接受”和“成功”,才会开始部署下一个存储帐户。

    Azure 门户活动日志的屏幕截图,其中按顺序显示了部署的三个存储帐户,并显示了相应时间戳和状态。

解决方案 3:获取外部资源

Bicep 使用符号名称来创建对另一个资源的隐式依赖关系existing 关键字引用已部署的资源。 如果现有资源与要部署的资源位于不同的资源组中,请包含 scope 并使用 resourceGroup 函数。

此示例将部署使用另一个资源组中现有应用服务计划的 Web 应用。

resource servicePlan 'Microsoft.Web/serverfarms@2022-03-01' existing = {
  name: hostingPlanName
  scope: resourceGroup(rgname)
}

resource webApp 'Microsoft.Web/sites@2022-03-01' = {
  name: siteName
  properties: {
    serverFarmId: servicePlan.id
  }
}

解决方案 4:从资源获取托管标识

如果部署具有托管标识的资源,则必须等到部署该资源后,才能检索托管标识上的值。 为应用了该标识的资源使用隐式依赖关系。 此方法可确保在资源管理器使用依赖关系之前部署资源和托管标识。

可以获取应用于虚拟机的托管标识的主体 ID 和租户 ID。 例如,如果虚拟机资源具有 vm 符号名称,请使用以下语法:

vm.identity.principalId

vm.identity.tenantId

解决方案 5:检查函数

可以使用资源的符号名称从资源中获取值。 可以使用符号名称引用同一资源组或另一资源组中的存储帐户。 若要从已部署的资源中获取值,请使用 existing 关键字。 如果资源位于其他资源组中,请将 scoperesourceGroup 函数结合使用。 在大多数情况下,不需要使用 reference 函数。

以下示例引用不同资源组中的现有存储帐户。

resource stgAcct 'Microsoft.Storage/storageAccounts@2022-05-01' existing = {
  name: stgname
  scope: resourceGroup(rgname)
}

解决方案 6:删除资源后

删除资源时,可能会有一小段时间,资源仍显示在门户中但不可用。 如果选择该资源,你会收到一条错误,指出“找不到”该资源。

Azure 门户的屏幕截图,其中显示了已删除的某个资源,以及该资源的“概述”中的“未找到”错误消息。

刷新门户,应会发现已删除的资源已从可用资源列表中删除。 如果已删除的资源有相当长一段时间仍显示为可用,请联系支持人员