Terraform中已有App Service配置Key Vault访问策略的依赖问题
问题
给已存在的App Service添加System Assigned托管身份,并在同一Terraform配置中创建Key Vault访问策略,引用该身份的principal_id作为object_id时,执行plan/apply报错:"The argument "object_id" is required, but no definition was found."。
使用depends_on无效,因为该属性在现有App Service的状态中不存在,且depends_on仅控制资源级别的依赖,无法感知属性的创建。分步执行(先添加身份再配置策略)或从零创建App Service时正常,但需要单次apply完成现有App Service的身份添加与策略配置。
代码示例:
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 ] }
解决方案
可以通过引入data资源延迟读取App Service的身份属性,确保在App Service完成身份添加后再获取principal_id,实现单次apply完成配置。
修改后的完整代码
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 } } # 延迟读取更新后的App Service信息,确保已获取到系统托管身份 data "azurerm_linux_web_app" "webapp1_updated" { name = azurerm_linux_web_app.webapp1.name resource_group_name = azurerm_linux_web_app.webapp1.resource_group_name depends_on = [azurerm_linux_web_app.webapp1] } 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 # 引用data资源中的principal_id object_id = data.azurerm_linux_web_app.webapp1_updated.identity[0].principal_id secret_permissions = ["Get"] depends_on = [data.azurerm_linux_web_app.webapp1_updated] }
原理说明
- Terraform会优先执行
azurerm_linux_web_app资源的更新操作,为现有App Service添加系统托管身份。 data资源通过depends_on依赖于更新后的App Service,确保在身份创建完成后才读取资源信息,此时principal_id已存在。- 访问策略资源依赖于
data资源,确保使用最新的principal_id配置访问策略,避免属性不存在的报错,实现单次apply完成所有配置。
内容的提问来源于stack exchange,提问作者b1ackhawk
相关产品推荐
相关产品推荐

