通过Terraform获取Azure系统分配托管标识的Client/Application ID
如何通过Terraform获取系统分配托管标识的Client ID用于Azure SQL用户创建
问题描述
我尝试用Terraform的mssql_user资源,为Web应用的系统分配托管标识在Azure SQL数据库中创建用户。由于没有Azure AD的Directory Readers角色,必须提供托管标识的Client ID(即Application ID)而非名称才能正常创建可登录的用户。
对于用户分配的托管标识,azurerm_user_assigned_identity资源直接暴露了client_id属性,配置能正常工作:
resource "mssql_user" "example" { server { host = "example-sql-server.database.windows.net" azure_login { } } database = "my-database" username = azurerm_user_assigned_identity.example.name object_id = azurerm_user_assigned_identity.example.client_id roles = ["db_datareader"] }
但系统分配的托管标识,其所属资源(比如azurerm_linux_web_app)的identity块仅提供principal_id,用这个值作为mssql_user的object_id虽然能创建用户,但该用户无法登录数据库。请问如何通过Terraform获取系统分配托管标识的Client ID?
解决方案
方法1:使用azuread_service_principal数据源
系统分配的托管标识本质是Azure AD中的服务主体,可通过其principal_id(即服务主体的Object ID)反向查询获取Client ID:
# 配置带系统分配托管标识的Web应用 resource "azurerm_linux_web_app" "example" { name = "example-webapp" resource_group_name = azurerm_resource_group.example.name location = azurerm_resource_group.example.location service_plan_id = azurerm_service_plan.example.id identity { type = "SystemAssigned" } } # 通过principal_id查询对应服务主体,提取client_id data "azuread_service_principal" "webapp_msi" { object_id = azurerm_linux_web_app.example.identity[0].principal_id } # 创建可正常登录的SQL用户 resource "mssql_user" "webapp_msi" { server { host = "example-sql-server.database.windows.net" azure_login { } } database = "my-database" username = azurerm_linux_web_app.example.name object_id = data.azuread_service_principal.webapp_msi.client_id roles = ["db_datareader"] }
方法2:通过ARM模板部署提取Client ID
如果无法使用Azure AD数据源(比如权限限制),可通过azurerm_resource_group_template_deployment执行ARM模板获取Client ID:
# 配置带系统分配托管标识的Web应用 resource "azurerm_linux_web_app" "example" { name = "example-webapp" resource_group_name = azurerm_resource_group.example.name location = azurerm_resource_group.example.location service_plan_id = azurerm_service_plan.example.id identity { type = "SystemAssigned" } } # 用ARM模板提取系统分配标识的client_id resource "azurerm_resource_group_template_deployment" "get_msi_client_id" { name = "get-msi-client-id" resource_group_name = azurerm_resource_group.example.name template_content = <<JSON { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "resourceId": { "type": "string" } }, "resources": [], "outputs": { "clientId": { "type": "string", "value": "[reference(parameters('resourceId'), '2023-01-01', 'Full').identity.clientId]" } } } JSON parameters = { resourceId = azurerm_linux_web_app.example.id } } # 使用提取到的client_id创建SQL用户 resource "mssql_user" "webapp_msi" { server { host = "example-sql-server.database.windows.net" azure_login { } } database = "my-database" username = azurerm_linux_web_app.example.name object_id = azurerm_resource_group_template_deployment.get_msi_client_id.outputs["clientId"] roles = ["db_datareader"] }
注意事项
- 使用
azuread_service_principal数据源时,执行Terraform的身份需要拥有Application.Read.All或类似Azure AD权限。 - 两种方法获取的Client ID传入
mssql_user的object_id字段后,即可创建可正常登录的Azure SQL数据库用户。
内容的提问来源于stack exchange,提问作者14207973
相关产品推荐
相关产品推荐

