You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 20:35:16