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

Azure Terraform:禁用公网访问的SQL Server导入bacpac方案

解决方案

针对禁用公网访问的Azure SQL Server,通过Terraform导入BACPAC文件且不开启公网访问,有以下几种可行方案:

方案1:托管身份+存储私有端点(推荐)

利用SQL Server的系统托管身份访问配置了私有端点的存储账户,全程在VNet内部完成数据传输:

  1. 为SQL Server启用系统分配托管身份,并赋予该身份对目标Blob容器的Storage Blob Data Reader权限。
  2. 给存储账户创建私有端点,确保SQL Server所在VNet能通过私有DNS解析存储账户的私有域名(如{storage-account}.privatelink.blob.core.windows.net)。
  3. 在Terraform的azurerm_mssql_database资源中,使用Identity认证类型指定存储的私有端点URL。

示例代码片段:

resource "azurerm_mssql_server" "sql_server" {
  name                         = "private-sql-server"
  resource_group_name          = azurerm_resource_group.rg.name
  location                     = azurerm_resource_group.rg.location
  version                      = "12.0"
  administrator_login          = "sqladmin"
  administrator_login_password = "StrongPass123!"
  public_network_access_enabled = false

  # 启用系统托管身份
  identity {
    type = "SystemAssigned"
  }
}

# 给SQL Server身份分配Blob读取权限
resource "azurerm_role_assignment" "sql_blob_reader" {
  scope                = azurerm_storage_container.bacpac_container.id
  role_definition_name = "Storage Blob Data Reader"
  principal_id         = azurerm_mssql_server.sql_server.identity[0].principal_id
}

resource "azurerm_mssql_database" "imported_db" {
  name           = "imported-db"
  server_id      = azurerm_mssql_server.sql_server.id
  collation      = "SQL_Latin1_General_CP1_CI_AS"
  license_type   = "LicenseIncluded"

  import {
    # 使用存储账户的私有端点URL
    storage_uri = "https://${azurerm_storage_account.bacpac_storage.name}.privatelink.blob.core.windows.net/${azurerm_storage_container.bacpac_container.name}/backup.bacpac"
    storage_authentication_type = "Identity" # 采用托管身份认证
  }
}

方案2:Terraform外部数据源调用Azure CLI

如果受限于网络或配置,可通过external数据源在能访问SQL私有端点的环境(如VNet内的虚拟机、Azure DevOps私有代理)执行Azure CLI的导入命令:

data "external" "import_bacpac" {
  program = [
    "az", "sql", "db", "import",
    "--resource-group", azurerm_resource_group.rg.name,
    "--server", azurerm_mssql_server.sql_server.name,
    "--name", "imported-db",
    "--storage-uri", "https://${azurerm_storage_account.bacpac_storage.name}.blob.core.windows.net/${azurerm_storage_container.bacpac_container.name}/backup.bacpac",
    "--storage-key", azurerm_storage_account.bacpac_storage.primary_access_key,
    "--admin-user", azurerm_mssql_server.sql_server.administrator_login,
    "--admin-password", azurerm_mssql_server.sql_server.administrator_login_password,
    "--no-wait"
  ]

  depends_on = [azurerm_mssql_server.sql_server, azurerm_storage_container.bacpac_container]
}

# 创建空数据库并依赖导入操作完成
resource "azurerm_mssql_database" "imported_db" {
  name           = "imported-db"
  server_id      = azurerm_mssql_server.sql_server.id
  collation      = "SQL_Latin1_General_CP1_CI_AS"
  license_type   = "LicenseIncluded"

  depends_on = [data.external.import_bacpac]
}

注意:执行Terraform的环境必须处于能访问SQL Server私有端点的网络中,且已完成Azure CLI身份认证。

方案3:切换至SQL托管实例(若架构允许)

如果业务架构允许,将SQL Server替换为Azure SQL托管实例——它本身部署在VNet内,默认可访问同VNet/对等VNet内的存储账户(只需存储账户防火墙允许VNet访问),此时Terraform的azurerm_mssql_managed_database资源的import块可直接完成导入,无需额外配置私有端点。

核心注意事项

  • 确保SQL Server VNet与存储私有端点VNet处于同一网络或已对等连接。
  • 私有DNS区域需正确配置,保证SQL Server能解析存储的私有域名。
  • AzureRM Provider 3.31版本已支持storage_authentication_type = "Identity",无需升级版本。

内容的提问来源于stack exchange,提问作者Lukas Hankeln

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 11:55:20