【问题标题】:Creating SQL Server vulnerability assessment resource using a private Storage Account fails使用私有存储帐户创建 SQL Server 漏洞评估资源失败
【发布时间】:2021-11-01 15:12:30
【问题描述】:

我有一个 SQL Server 资源,我尝试使用 Terraform 创建一个azurerm_mssql_server_vulnerability_assessment。为此,我使用的是私有存储帐户(没有公共访问/私有端点)。我的代码如下:

resource "azurerm_mssql_server_security_alert_policy" "mssql_security_alert_policy" {
  resource_group_name = var.resource_group_name
  server_name         = azurerm_mssql_server.this.name
  state               = "Enabled"
}

resource "azurerm_mssql_server_vulnerability_assessment" "mssql_vulnerability_assessment" {
  server_security_alert_policy_id = azurerm_mssql_server_security_alert_policy.mssql_security_alert_policy.id
  storage_container_path          = "${azurerm_storage_account.sql_defender_storage_account.primary_blob_endpoint}${azurerm_storage_container.sql_defender_storage_account_container.name}/"
  storage_account_access_key      = azurerm_storage_account.sql_defender_storage_account.primary_access_key

  recurring_scans {
    enabled = true
  }
}

# Allow the database to act as a contributor to the storage account for vulnerability assessments
resource "azurerm_role_assignment" "sql_blob_container_contributor" {
  principal_id = azurerm_mssql_server.this.identity[0].principal_id
  role_definition_name = "Storage Blob Data Contributor"
  scope        = azurerm_storage_account.sql_defender_storage_account.id
}

对于存储帐户:

resource "azurerm_storage_account" "sql_defender_storage_account" {
  name                     = "sqldefender${var.stage}"
  account_replication_type = "LRS"
  account_tier             = "Standard"
  location                 = var.location
  resource_group_name      = var.resource_group_name

  network_rules {
    default_action = var.deny_public_access ? "Deny" : "Allow"
    bypass = [
      "AzureServices", "Logging", "Metrics"
    ]

    private_link_access {
      endpoint_resource_id = azurerm_mssql_server.this.id
    }
    
  }

  tags = module.label_mssql_server.tags
}

resource "azurerm_private_endpoint" "mssql_server_defender_storage_account" {
  location            = var.location
  name                = "pe-to-${var.private_endpoint_name}-${azurerm_storage_account.sql_defender_storage_account.name}-blob"
  resource_group_name = var.resource_group_name
  subnet_id           = var.private_endpoints_subnet_id
  tags                = module.label_mssql_server.tags

  private_service_connection {
    is_manual_connection           = false
    //noinspection HILUnresolvedReference
    name                           = "private-serviceconnection"
    private_connection_resource_id = azurerm_storage_account.sql_defender_storage_account.id
    subresource_names              = [
      "blob"
    ]
  }
}

# Create a DNS record for the private storage account
resource "azurerm_private_dns_a_record" "sql_defender_storage_account" {
  provider = azurerm.common

  name    = azurerm_storage_account.sql_defender_storage_account.name
  records = azurerm_private_endpoint.mssql_server_defender_storage_account.custom_dns_configs.0.ip_addresses

  resource_group_name = var.common_resource_group_name
  ttl                 = 300
  zone_name           = var.blob_storage_dns_zone
  tags                = module.label_mssql_server.tags
}

# Create the storage account name
resource "azurerm_storage_container" "sql_defender_storage_account_container" {
  name                  = "sqldefendercontainer"
  storage_account_name  = azurerm_storage_account.sql_defender_storage_account.name
  container_access_type = "private"
  depends_on = [ azurerm_private_dns_a_record.sql_defender_storage_account ]
}

但是,当尝试应用创建的计划时,我收到以下错误:

错误:更新 mssql 服务器漏洞评估:sql.ServerVulnerabilityAssessmentsClient#CreateOrUpdate:响应请求失败:StatusCode=504 --

原始错误:autorest/azure:服务返回错误。

Status=504 Code="GatewayTimeout" Message="网关在指定时间段内没有收到来自'Microsoft.Sql'的响应。"

我不太确定为什么会这样。我怀疑它可能与私有端点有关,但我不是 100% 确定。任何人都可以在这里解释一下吗?

【问题讨论】:

  • 你好@akortex,我可以知道是否也为sql server启用了私有端点?还是它唯一的存储帐户?
  • 也为 sql server 启用了私有端点
  • @AnsumanBal-MT 为了满足 ISO 合规性规则,我需要将所有内容保密。但是,当锁定所有内容时,为数据库添加漏洞评估是不可行的。相反,当拥有公共存储帐户时,一切正常。
  • 是的,你是对的,我尝试了同样的方法,它提供了与你收到的相同的错误,但是当我创建完全相同的东西时,它从门户成功......,我观察到它创建了一个系统-服务器的托管标识并为其分配存储 blob 数据贡献者的角色,这就是它成功的原因.. 我正在测试相同的 terraform 会让你知道。
  • 嗯,这很有道理。我尝试了与您提到的扩展审计策略相同的事情(这似乎还需要系统分配的身份和角色)——但它不起作用。不过,我还没有尝试过这个评估。我也没有像您那样考虑检查 ARM 模板。如果你有任何成功,请告诉我。

标签: azure terraform azure-sql-database


【解决方案1】:

正如我在 cmets 中提到的,我们需要为 SQL Server 使用托管标识,然后为从 terraform 创建的存储提供相同的标识Storage Blob Data Contributor

我在现有 SQL Server 上启用了系统托管标识,然后通过 terraform 代码提供了存储 Blob 数据贡献者。

然后我使用以下代码来满足您的要求:

provider "azurerm" {
  features{}
}

#SystemMangedIdentity For the SQL Server
data "azuread_service_principal" "sqlsystemidentity" {
   display_name = "ansuman-sql"
}
data "azurerm_resource_group" "rg" {
  name = "myresourcegroup"
}
data "azurerm_virtual_network" "vnet" {
  name = "ansuman-vnet"
  resource_group_name = data.azurerm_resource_group.rg.name
}
data "azurerm_subnet" "subnet" {
  name = "storage"
  virtual_network_name = data.azurerm_virtual_network.vnet.name
  resource_group_name = data.azurerm_resource_group.rg.name
}

data "azurerm_mssql_server" "server" {
  name = "ansuman-sql"
  resource_group_name = data.azurerm_resource_group.rg.name
}

resource "azurerm_storage_account" "sql_defender_storage_account" {
  name                     = "sqldefenderansuman123"
  account_replication_type = "LRS"
  account_tier             = "Standard"
  location                 = data.azurerm_resource_group.rg.location
  resource_group_name      = data.azurerm_resource_group.rg.name
  network_rules {
    default_action = "Deny"
    ip_rules = ["myclientip"]
    bypass = [
      "AzureServices", "Logging", "Metrics"
    ]
  }
}

resource "azurerm_role_assignment" "sqltoblobcontributor" {
  scope                = azurerm_storage_account.sql_defender_storage_account.id
  role_definition_name = "Storage Blob Data Contributor"
  principal_id         = data.azuread_service_principal.sqlsystemidentity.object_id
}

resource "azurerm_private_endpoint" "mssql_server_defender_storage_account" {
  location            = data.azurerm_resource_group.rg.location
  name                = "pe-to-ansumanprivate-${azurerm_storage_account.sql_defender_storage_account.name}-blob"
  resource_group_name = data.azurerm_resource_group.rg.name
  subnet_id           = data.azurerm_subnet.subnet.id

  private_service_connection {
    is_manual_connection           = false
    //noinspection HILUnresolvedReference
    name                           = "private-serviceconnection"
    private_connection_resource_id = azurerm_storage_account.sql_defender_storage_account.id
    subresource_names              = [
      "blob"
    ]
  }
}

# private DNS
resource "azurerm_private_dns_zone" "example" {
  name                = "privatelink.blob.core.windows.net"
  resource_group_name = data.azurerm_resource_group.rg.name
  depends_on = [
    azurerm_private_endpoint.mssql_server_defender_storage_account
  ]
}

#private DNS Link
resource "azurerm_private_dns_zone_virtual_network_link" "example" {
  name                  = "${azurerm_storage_account.sql_defender_storage_account.name}-dnslink"
  resource_group_name   = data.azurerm_resource_group.rg.name
  private_dns_zone_name = azurerm_private_dns_zone.example.name
  virtual_network_id    = data.azurerm_virtual_network.vnet.id
  registration_enabled = false
}

# Create the storage account name
resource "azurerm_storage_container" "sql_defender_storage_account_container" {
  name                  = "sqldefendercontainer"
  storage_account_name  = azurerm_storage_account.sql_defender_storage_account.name
  container_access_type = "private"
  depends_on = [ azurerm_private_dns_zone_virtual_network_link.example]
}

resource "azurerm_mssql_server_security_alert_policy" "mssql_security_alert_policy" {
  resource_group_name = data.azurerm_resource_group.rg.name
  server_name         = data.azurerm_mssql_server.server.name
  state               = "Enabled"
}

resource "azurerm_mssql_server_vulnerability_assessment" "mssql_vulnerability_assessment" {
  server_security_alert_policy_id = azurerm_mssql_server_security_alert_policy.mssql_security_alert_policy.id
  storage_container_path          = "${azurerm_storage_account.sql_defender_storage_account.primary_blob_endpoint}${azurerm_storage_container.sql_defender_storage_account_container.name}/"
}

注意:

我从漏洞评估块中删除了存储访问密钥参数,因为它是可选的,在使用身份时不是必需的。

输出:

【讨论】:

  • 我遵循了您的建议,但不幸的是我仍然无法使其正常工作。我还像您一样启用了系统管理的身份,而且我还为存储帐户设置了私有访问链接网络规则。但是,在尝试应用配置时,我仍然遇到相同的 504 错误。
  • 我还看到您没有为漏洞评估资源提供storage_access_key。这不需要吗?
  • 您好@akortex 是的,正如我在答案中提到的那样,在使用我们不需要访问密钥的托管标识时,它不需要。因为将提供对身份的访问权限作为 rbac 角色,即存储 blob 数据贡献者。
猜你喜欢
  • 2021-02-25
  • 2021-10-29
  • 2017-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多