如何通过Terraform为AzureAD应用注册授予自身API权限?
问题描述
我需要给Terraform脚本中的app_registration应用注册授予自身定义的API权限,尝试添加required_resource_access段时,将resource_app_id设为应用ID会触发循环引用错误。此外,我还希望将identifier_uris设置为应用的UUID,但目前无法实现。
Azure门户手动操作步骤:
- 访问portal.azure.com
- 切换至应用所在的目录
- 从左上角汉堡菜单选择“Azure Active Directory”
- 点击“应用注册”
- 选中目标应用
- 点击“API权限”
- 点击“添加权限”
- 选择“我的API”标签页
- 在列表中选中自身应用
- 勾选“access_as_user”权限
- 点击“添加权限”
原Terraform脚本:
data "azuread_client_config" "current" {} data "azuread_application_published_app_ids" "well_known" {} resource "random_uuid" "app_scope_id" {} resource "azuread_service_principal" "msgraph" { application_id = data.azuread_application_published_app_ids.well_known.result.MicrosoftGraph use_existing = true } resource "azuread_application" "app_registration" { display_name = "My app name" identifier_uris = ["api://${var.environment}productname"] owners = [data.azuread_client_config.current.object_id] sign_in_audience = "AzureADMultipleOrgs" api { mapped_claims_enabled = true # requested_access_token_version = 2 oauth2_permission_scope { admin_consent_description = "Allow the application to access a user's name and email address." admin_consent_display_name = "Access user name and email address" enabled = true id = random_uuid.app_scope_id.result type = "User" user_consent_description = "Allow the application to access your name and email address." user_consent_display_name = "Access your name and email address" value = "access_as_user" } } required_resource_access { resource_app_id = data.azuread_application_published_app_ids.well_known.result.MicrosoftGraph // "00000003-0000-0000-c000-000000000000" resource_access { id = azuread_service_principal.msgraph.oauth2_permission_scope_ids["User.Read"] // "e1fe6dd8-ba31-4d61-89e7-88639da4683d" type = "Scope" } resource_access { id = azuread_service_principal.msgraph.oauth2_permission_scope_ids["email"] // "37f7f235-527c-4136-accd-4a02d197296e" type = "Scope" } resource_access { id = azuread_service_principal.msgraph.oauth2_permission_scope_ids["openid"] // "64a6cdd6-aab1-4aaf-94b8-3cc8405e90d0" type = "Scope" } } web { homepage_url = "https://${var.environment}productname.azurewebsites.net" logout_url = "https://${var.environment}productname.azurewebsites.net/logout" redirect_uris = ["https://${var.environment}productname.azurewebsites.net//authentication/login-callback"] implicit_grant { access_token_issuance_enabled = true id_token_issuance_enabled = true } } }
解决方案
1. 解决自身API权限的循环引用问题
循环引用是因为在azuread_application资源内部直接引用自身未创建完成的application_id导致的。可以通过拆分资源、明确依赖关系解决:
修改步骤:
- 创建应用注册对应的服务主体(依赖已创建的应用注册):
resource "azuread_service_principal" "app_registration" { application_id = azuread_application.app_registration.application_id depends_on = [azuread_application.app_registration] }
- 使用单独的资源管理自身API权限:
resource "azuread_application_required_resource_access" "self_permission" { application_id = azuread_application.app_registration.id required_resource_access { resource_app_id = azuread_service_principal.app_registration.application_id resource_access { id = random_uuid.app_scope_id.result # 对应自定义的access_as_user权限ID type = "Scope" } } }
通过这种方式,让权限配置依赖已创建完成的应用注册和服务主体,彻底避免循环引用。
2. 将identifier_uris设置为UUID
直接引用自身application_id会触发循环引用,推荐使用预先生成的随机UUID作为标识:
修改步骤:
- 生成随机UUID资源:
resource "random_uuid" "app_identifier" {}
- 更新应用注册的
identifier_uris配置:
resource "azuread_application" "app_registration" { display_name = "My app name" identifier_uris = ["api://${random_uuid.app_identifier.result}"] owners = [data.azuread_client_config.current.object_id] sign_in_audience = "AzureADMultipleOrgs" # 其他原有配置保持不变 }
如果一定要使用Azure自动生成的application_id作为标识,需要在应用注册创建后通过额外资源更新,但这种方式可能导致Terraform状态不一致,不推荐使用。
内容的提问来源于stack exchange,提问作者Peter Morris
相关产品推荐
相关产品推荐

