使用Terraform部署Azure前后端应用注册时出现循环依赖及配置报错
我需要注册两个应用,分别为前端应用与后端应用,二者也对应有各自的Web App资源。我使用Terraform部署所有应用及整套基础设施,但执行terraform plan命令时出现报错,相关代码如下:
前端Web App代码
resource "azurerm_app_service" "fe" { location = module.resourcegroup.resource_group.location resource_group_name = module.resourcegroup.resource_group.name tags = module.resourcegroup.resource_group.tags app_service_plan_id = azurerm_app_service_plan.default.id name = module.names-web-app-fe.location.app_service.name_unique identity { type = "SystemAssigned" } auth_settings { enabled = true default_provider = "AzureActiveDirectory" issuer = format("https://sts.windows.net/%s/", data.azurerm_client_config.default.tenant_id) runtime_version = "~1" token_store_enabled = true unauthenticated_client_action = "RedirectToLoginPage" additional_login_params = { "response_type" = "code id_token", "resource" = azuread_application.app-fe.application_id } active_directory { client_id = azuread_application.app-fe.object_id client_secret = azuread_application_password.fe-app-sp-secret.application_object_id allowed_audiences = [format("https://%s.azurewebsites.net", module.names-web-app-fe.location.app_service.name_unique)] } } site_config { always_on = true app_command_line = "" default_documents = [] dotnet_framework_version = "v4.0" ftps_state = "Disabled" health_check_path = "" http2_enabled = true linux_fx_version = "STATICSITE|1.0" local_mysql_enabled = false managed_pipeline_mode = "Integrated" min_tls_version = "1.2" #pre_warmed_instance_count = 0 python_version = "3.4" remote_debugging_enabled = false remote_debugging_version = "VS2019" use_32_bit_worker_process = false websockets_enabled = false windows_fx_version = "" cors { allowed_origins = [] support_credentials = false } } app_settings = { "WEBSITE_DNS_SERVER" = "168.63.129.16" "WEBSITE_VNET_ROUTE_ALL" = "1" } }
后端Web App代码
resource "azurerm_app_service" "be" { location = module.resourcegroup.resource_group.location resource_group_name = module.resourcegroup.resource_group.name tags = module.resourcegroup.resource_group.tags app_service_plan_id = azurerm_app_service_plan.default.id name = module.names-web-app-be.location.app_service.name_unique identity { type = "SystemAssigned" } auth_settings { enabled = true default_provider = "AzureActiveDirectory" issuer = format("https://sts.windows.net/%s/", data.azurerm_client_config.default.tenant_id) runtime_version = "~1" token_store_enabled = true unauthenticated_client_action = "RedirectToLoginPage" additional_login_params = { "response_type" = "code id_token", "resource" = azuread_application.app-be.application_id } active_directory { client_id = azuread_application.app-be.object_id client_secret = azuread_application_password.be-app-sp-secret.application_object_id allowed_audiences = [] } } site_config { always_on = true app_command_line = "" default_documents = [] dotnet_framework_version = "v4.0" ftps_state = "AllAllowed" health_check_path = "" http2_enabled = true linux_fx_version = "DOTNETCORE|3.1" local_mysql_enabled = false managed_pipeline_mode = "Integrated" min_tls_version = "1.2" python_version = "3.4" remote_debugging_enabled = false remote_debugging_version = "VS2019" use_32_bit_worker_process = false windows_fx_version = "" websockets_enabled = true cors { allowed_origins = [format("https://%s", azurerm_app_service.fe.default_site_hostname)] support_credentials = true } } app_settings = { "WEBSITE_DNS_SERVER" = "168.63.129.16" "WEBSITE_VNET_ROUTE_ALL" = "1" } }
UUID生成代码
resource "random_uuid" "qb2-sal" {}
前端应用注册代码
resource "azuread_application" "app-fe" { display_name = format("%s-fe", var.project.name) api { oauth2_permission_scope { admin_consent_description = "Allows the app to read and write data" admin_consent_display_name = local.oauth2_permissions.read-and-write.admin_consent_display_name enabled = true id = random_uuid.qb2-sal.results type = "User" value = "read-and-write" } } app_role { allowed_member_types = ["User", "Application"] description = "Application administrators have the ability to administer the application." display_name = local.app_roles.application-administrator.display_name enabled = true id = "02c4e591-d667-51db-5597-e2c446ec246b" value = "application-administrator" } web { logout_url = format("https://%s.azurewebsites.net/.auth/logout", module.names-web-app-fe.location.app_service.name_unique) redirect_uris = [format("https://%s.azurewebsites.net/.auth/login/aad/callback", module.names-web-app-fe.location.app_service.name_unique)] implicit_grant { access_token_issuance_enabled = true id_token_issuance_enabled = true } } required_resource_access { resource_app_id = azuread_application.app-be.application_id # Microsoft Graph resource_access { id = "02c4e591-d667-51db-5597-e2c446ec246b" # User.Read.All type = "Role" } } }
前端服务主体密码代码
resource "azuread_application_password" "fe-app-sp-secret" { application_object_id = azuread_application.app-fe.object_id }
后端应用注册代码
resource "azuread_application" "app-be" { display_name = format("%s-be", var.project.name) api { oauth2_permission_scope { admin_consent_description = "Allows the app to read and write data" admin_consent_display_name = local.oauth2_permissions.read-and-write.admin_consent_display_name enabled = true id = random_uuid.qb2-sal.result type = "User" value = "read-and-write" } } app_role { allowed_member_types = ["User", "Application"] description = "Application administrators have the ability to administer the application." display_name = local.app_roles.application-administrator.display_name enabled = true id = "02c4e591-d667-51db-5597-e2c446ec246b" value = "application-administrator" } web { logout_url = format("https://%s.azurewebsites.net/.auth/logout", module.names-web-app-be.location.app_service.name_unique) redirect_uris = [format("https://%s.azurewebsites.net/.auth/login/aad/callback", module.names-web-app-be.location.app_service.name_unique)] implicit_grant { access_token_issuance_enabled = true id_token_issuance_enabled = true } } }
后端服务主体密码代码
resource "azuread_application_password" "be-app-sp-secret" { application_object_id = azuread_application.app-be.object_id }
执行terraform plan时的报错信息
Error: .group_membership_claims: missing expected [
问题排查与修复方案
报错原因
- 你使用的Azure AD Terraform Provider版本要求
azuread_application资源必须显式声明group_membership_claims参数,该参数为数组类型,未声明就会触发缺少[的报错。 - 代码存在笔误:前端应用注册的
oauth2_permission_scope块中,UUID引用写的是random_uuid.qb2-sal.results,多了末尾的s,正确属性名是result。 - 你提到的循环依赖问题来自前端应用注册的
required_resource_access块直接引用后端应用注册的application_id,如果后续有反向依赖就会形成死循环。
修复步骤
- 给前后端两个
azuread_application资源都添加group_membership_claims参数,可根据实际需求赋值,不需要该配置可以设为空数组,示例:
resource "azuread_application" "app-fe" { display_name = format("%s-fe", var.project.name) group_membership_claims = [] # 新增该行,可根据需求替换为["SecurityGroup"]、["All"]等值 api { oauth2_permission_scope { # 其他配置不变 id = random_uuid.qb2-sal.result # 修正这里的笔误,去掉末尾的s # 其他配置不变 } } # 其余原有配置保持不变 }
后端应用注册资源同理添加group_membership_claims参数即可。
2. 若要消除循环依赖,可调整架构将后端应用注册的创建与前端应用注册的依赖拆分,或者提前预定义后端应用的客户端ID作为变量传入,避免运行时互相引用。
内容的提问来源于stack exchange,提问作者Pallab
相关产品推荐
相关产品推荐

