#azure #terraform #azure-sql-database
Вопрос:
У меня есть ресурс SQL Server, для которого я пытаюсь создать с azurerm_mssql_server_vulnerability_assessment
помощью Terraform. Для этого я использую частную учетную запись хранения (без открытого доступа / частных конечных точек). Мой код для этого следующий:
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 —
Исходная ошибка: автотест/azure: Служба вернула ошибку.
Статус=504 Код=»GatewayTimeout» Сообщение=»Шлюз не получил ответа от» Microsoft.Sql «в течение указанного периода времени».
Я действительно не уверен, почему это происходит. Я подозреваю, что это может быть связано с частными конечными точками, но я не уверен на 100%. Может ли кто-нибудь потенциально пролить здесь немного света?
Комментарии:
1. здравствуйте, @akortex, могу я узнать, включена ли частная конечная точка также для sql server? или его единственная учетная запись хранения ?
2. Частные конечные точки также включены для sql server
3. @AnsumanBal-MT Мне нужно, чтобы все было конфиденциально, чтобы соответствовать правилам соответствия ISO. Однако при блокировке всего добавление оценки уязвимости для базы данных нецелесообразно. Напротив, при наличии общедоступной учетной записи хранения все работает нормально.
4. да , вы правы , я попробовал то же самое, и он выдает ту же ошибку, что и вы, но когда я создаю то же самое, что и на портале.., я заметил, что он создает управляемую системой идентификацию для сервера и назначает ему роль поставщика данных blob-объектов для хранения, и вот почему это удается .. я тестирую то же самое для terraform, сообщу вам.
5. Ха, это может иметь смысл. Я попробовал то же самое, что вы упомянули, для политики расширенного аудита (для которой, похоже, также требуется присвоенная системе личность и роль), но это не сработало. Однако я не пробовал это для оценки. Я также не подумал проверить шаблон РУКИ, как это сделали вы. Дайте мне знать, если у вас будет какой-нибудь успех.
Ответ №1:
Как я уже упоминал в комментариях , нам требуется использовать Управляемое удостоверение для SQL Server, а затем предоставить такое же удостоверение Storage Blob Data Contributor
для хранилища, созданного из terraform.
Я включил Системную управляемую идентификацию на существующем SQL-сервере, а затем предоставил поставщик данных Blob-объектов для хранения из кода terraform.
Затем я использовал приведенный ниже код для требования, которое у вас есть :
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}/" }
Примечание:
Я удалил параметр ключа доступа к хранилищу из блока оценки уязвимости, так как он будет необязательным и не требуется при использовании удостоверений.
Выход:
Комментарии:
1. Я последовал вашей рекомендации и, к сожалению, до сих пор не могу заставить ее работать. Я также включил системную управляемую идентификацию, как и вы, и, кроме того, я также установил сетевое правило канала частного доступа для учетной записи хранения. Однако при попытке применить конфигурацию я все еще получаю ту же ошибку 504.
2. Я также вижу, что вы не предоставили
storage_access_key
ресурс для оценки уязвимости. Разве в этом нет необходимости?3. Привет @akortex да, это не нужно, как я уже упоминал в ответе, при использовании управляемой идентификации нам не требуется ключ доступа . Поскольку доступ будет предоставлен для идентификации в качестве роли rbac, т. е. участника данных больших двоичных объектов хранилища.