如何通过Terraform从托管标识创建Azure SQL数据库用户?
通过Terraform为AD标识创建SQL数据库用户并分配角色
现有方案的局限
我目前通过以下Terraform代码创建SQL服务器,将安全组设为AD管理员,再把Web服务的系统分配标识加入该组,以此实现服务对数据库的访问:
variable "app_service" { } data "azuread_client_config" "current" {} # 创建安全组 resource "azuread_group" "grp_1" { display_name = "appname-sqladmin" owners = [data.azuread_client_config.current.object_id] security_enabled = true } # 创建SQL服务器 resource "azurerm_mssql_server" "sqlsvr" { name = "appname-sqlsvr" resource_group_name = "resource_group_name" location = "resource_group_location" version = "12.0" azuread_administrator { login_username = azuread_group.grp_1.display_name object_id = azuread_group.grp_1.id azuread_authentication_only = true } } # 创建SQL数据库 resource "azurerm_mssql_database" "sqldb" { name = "appname-sqldb" server_id = azurerm_mssql_server.sqlsvr.id max_size_gb = 1 sku_name = "Basic" storage_account_type = "Local" } # 将应用服务标识加入安全组 resource "azuread_group_member" "grp_mbr_1" { group_object_id = azuread_group.grp_1.id member_object_id = var.app_service.identity.0.principal_id }
该方案可以正常运行,但存在权限过大的问题:服务会获得整个SQL服务器的管理员权限,而非仅目标数据库的访问权限。
需求
能否直接通过Terraform创建映射到AD标识的数据库用户,并为其分配指定的数据库角色?且我的Terraform运行在Windows桌面和Azure Linux构建代理上,不想依赖CLI脚本或不同环境的CLI工具。
解决方案
可以通过Terraform的azurerm_mssql_user和azurerm_mssql_role_assignment资源实现,无需依赖外部CLI:
步骤1:创建映射AD标识的数据库用户
使用azurerm_mssql_user资源,指定azuread_principal_id为应用服务的系统分配标识ID,关联到目标数据库:
# 创建映射应用服务AD标识的数据库用户 resource "azurerm_mssql_user" "app_db_user" { name = "app-service-db-user" database_id = azurerm_mssql_database.sqldb.id azuread_principal_id = var.app_service.identity.0.principal_id }
步骤2:为数据库用户分配角色
使用azurerm_mssql_role_assignment资源,将用户添加到数据库的内置角色(比如db_datareader、db_datawriter)或自定义角色:
# 为用户分配数据读取权限 resource "azurerm_mssql_role_assignment" "app_db_reader" { database_id = azurerm_mssql_database.sqldb.id role_name = "db_datareader" principal_id = azurerm_mssql_user.app_db_user.id } # 可选:分配数据写入权限 resource "azurerm_mssql_role_assignment" "app_db_writer" { database_id = azurerm_mssql_database.sqldb.id role_name = "db_datawriter" principal_id = azurerm_mssql_user.app_db_user.id }
完整优化后代码
整合后的代码如下,移除了原有的服务器级管理员安全组,改用数据库级权限控制:
variable "app_service" { } data "azuread_client_config" "current" {} # 创建SQL服务器 resource "azurerm_mssql_server" "sqlsvr" { name = "appname-sqlsvr" resource_group_name = "resource_group_name" location = "resource_group_location" version = "12.0" # 可选:保留AD服务器管理员(用于运维),但不再将应用服务加入该组 azuread_administrator { login_username = data.azuread_client_config.current.client_id object_id = data.azuread_client_config.current.object_id azuread_authentication_only = true } } # 创建SQL数据库 resource "azurerm_mssql_database" "sqldb" { name = "appname-sqldb" server_id = azurerm_mssql_server.sqlsvr.id max_size_gb = 1 sku_name = "Basic" storage_account_type = "Local" } # 创建映射应用服务AD标识的数据库用户 resource "azurerm_mssql_user" "app_db_user" { name = "app-service-db-user" database_id = azurerm_mssql_database.sqldb.id azuread_principal_id = var.app_service.identity.0.principal_id } # 为用户分配数据库角色 resource "azurerm_mssql_role_assignment" "app_db_reader" { database_id = azurerm_mssql_database.sqldb.id role_name = "db_datareader" principal_id = azurerm_mssql_user.app_db_user.id } resource "azurerm_mssql_role_assignment" "app_db_writer" { database_id = azurerm_mssql_database.sqldb.id role_name = "db_datawriter" principal_id = azurerm_mssql_user.app_db_user.id }
说明
- 该方案直接在数据库级别创建AD用户并分配最小必要权限,避免了服务器级管理员权限的过度授予。
- 所有操作均通过Terraform资源完成,无需调用任何CLI命令,兼容Windows和Linux环境。
- 可以根据实际需求调整角色(比如仅分配
db_datareader,或自定义数据库角色)。
内容的提问来源于stack exchange,提问作者Neutrino
相关产品推荐
相关产品推荐

