由于缺少将创建的引用属性,导致地形在创建资源时出错的问题



我希望为应用服务添加一个密钥库访问策略,该策略将使用应用服务管理的身份。如果我将所需的身份属性添加为类型"System assigned";到应用程序服务和密钥库访问策略引用的"待用";为现有应用程序服务的托管身份创建对象id,我在计划/应用期间得到一个错误,说明参数"object_id"是必需的,但没有找到定义。代码示例:

resource "azurerm_linux_web_app" "webapp1" {
name                = "app-web-myapp-test3"
resource_group_name = azurerm_resource_group.secondary_rg.name
location            = azurerm_resource_group.secondary_rg.location
service_plan_id     = data.terraform_remote_state.shared_resources.outputs.primary_plan_id
identity {
type = "SystemAssigned"
}
site_config {
always_on = false
}
}

resource "azurerm_key_vault_access_policy" "secondary_policy" {
key_vault_id = data.terraform_remote_state.shared_resources.outputs.primary_vault_id
tenant_id    = data.azurerm_client_config.current.tenant_id
object_id          = azurerm_linux_web_app.webapp1.identity.0.principal_id
secret_permissions = ["Get", ]
depends_on = [
azurerm_linux_web_app.webapp1
]
}

在App Service中使用依赖于没有帮助,因为资源已经存在(但不是必需的属性),因此失败。依赖于不允许在属性上使用自己,只能在资源上使用。如果我首先将托管身份更改应用于应用程序服务,然后在完成后添加密钥库策略,它会正常工作。如果我在创建应用服务之前从头开始运行它,它会等待使用托管身份创建应用服务,并且工作正常。但是,我想保持应用程序服务的位置,并在相同的应用程序中应用这些更改。如何处理这个依赖关系?

Terraform中的依赖项仅用于决定采取行动的顺序,而不是决定实际采取什么行动。在你的情况下,听起来这不是依赖关系的问题,而是不支持配置的问题。

Terraform将首先要求hashicorp/azurerm提供者计划对azurerm_linux_web_app.webapp1的更改,然后使用该结果中的值来填充azurerm_key_vault_access_policy.secondary_policy的配置。

为了使第二个资源的配置有效,第一个资源的计划必须在.identity[0].principal_id中包含一个非空值。你的配置没有设置principal_id,很明显,提供者没有为它插入任何默认值,所以结果是无效的。

实现此功能的一种方法是在identity中显式地设置principal_id,在这种情况下,引用将返回相同的值。


不幸的是,我认为提供者似乎缺少一些逻辑来正确处理principal_id由远程系统而不是由您的配置决定的情况。

如果我正确理解了这些特性的工作方式,我认为提供者应该在计划阶段将principal_id属性设置为(known after apply),如果它打算在应用阶段使用实际值填充它。这将允许下游资源看到principal_id将在应用期间有一个值,从而避免引发此验证错误。

没有办法通过更改Terraform代码来修复丢失的逻辑,除非您可以在配置中指定显式的principal_id。在计划阶段,描述资源的计划最终状态是提供者的责任,如果提供者没有对这个问题返回正确的答案,那么下游操作将根据不正确的信息进行操作,因此可能会像您在这里看到的那样失败。如果这是你的情况,那么我认为接下来要做的最好的事情是在hashicorp/azurerm提供程序存储库中打开一个关于它的问题,以便提供程序团队可以调查为什么提供程序在规划期间没有正确设置此属性。

这个方法也适用于web应用程序:https://github.com/hashicorp/terraform-provider-azurerm/issues/19316

本质上是指引用数据源而不是直接引用资源。