使用私有存储帐户创建 SQL 服务器漏洞评估资源失败
Creating SQL Server vulnerability assessment resource using a private Storage Account fails
我有一个 SQL 服务器资源,我尝试使用 Terraform 为其创建一个 azurerm_mssql_server_vulnerability_assessment
。为此,我使用了一个私人存储帐户(没有 public 访问/私人端点)。我的代码如下:
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 ]
}
然而,在尝试应用创建的计划时,出现以下错误:
Error: updataing mssql server vulnerability assessment: sql.ServerVulnerabilityAssessmentsClient#CreateOrUpdate: Failure responding to request: StatusCode=504 --
Original Error: autorest/azure: Service returned an error.
Status=504 Code="GatewayTimeout" Message="The gateway did not receive a response from 'Microsoft.Sql' within the specified time period."
我不太确定为什么会这样。我怀疑这可能与专用端点有关,但我不是 100% 确定。任何人都可以在这里阐明一些信息吗?
正如我在评论中提到的,我们需要为 SQL 服务器使用托管身份,然后为从 terraform 创建的存储提供相同的身份 Storage Blob Data Contributor
。
我在现有 SQL 服务器上启用了系统管理身份,然后从 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}/"
}
注:
我从漏洞评估块中删除了存储访问密钥参数,因为它是可选的,在使用身份时不是必需的。
输出:
我有一个 SQL 服务器资源,我尝试使用 Terraform 为其创建一个 azurerm_mssql_server_vulnerability_assessment
。为此,我使用了一个私人存储帐户(没有 public 访问/私人端点)。我的代码如下:
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 ]
}
然而,在尝试应用创建的计划时,出现以下错误:
Error: updataing mssql server vulnerability assessment: sql.ServerVulnerabilityAssessmentsClient#CreateOrUpdate: Failure responding to request: StatusCode=504 --
Original Error: autorest/azure: Service returned an error.
Status=504 Code="GatewayTimeout" Message="The gateway did not receive a response from 'Microsoft.Sql' within the specified time period."
我不太确定为什么会这样。我怀疑这可能与专用端点有关,但我不是 100% 确定。任何人都可以在这里阐明一些信息吗?
正如我在评论中提到的,我们需要为 SQL 服务器使用托管身份,然后为从 terraform 创建的存储提供相同的身份 Storage Blob Data Contributor
。
我在现有 SQL 服务器上启用了系统管理身份,然后从 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}/"
}
注:
我从漏洞评估块中删除了存储访问密钥参数,因为它是可选的,在使用身份时不是必需的。
输出: