Создайте правила брандмауэра SQL на сервере SQL, используя таргетинг - PullRequest
0 голосов
/ 21 октября 2019

У меня есть azurerm_sql_server и два azurerm_sql_firewall_rule s для этого сервера.

Если я выберу целевой terraform apply для создания ресурса в зависимости от сервера SQL, сервер SQL будет создан, но серверправила брандмауэра не применяются.

Можно ли требовать, чтобы правила брандмауэра всегда развертывались на сервере SQL?

«Бонус»: сервер SQL находится в модуле, а база данных, использующая сервер, -в другом модуле: (

Пример кода:

structure / main.tf

resource "azurerm_sql_server" "test" {
    count = var.enable_dbs ? 1 : 0

    location            = azurerm_resource_group.test.location
    resource_group_name = azurerm_resource_group.test.name

    name                         = local.dbs_name
    version                      = "12.0"
    administrator_login          = var.dbs_admin_login
    administrator_login_password = var.dbs_admin_password
}

resource "azurerm_sql_firewall_rule" "allow_azure_services" {
    count = var.enable_dbs ? 1 : 0

    resource_group_name = azurerm_resource_group.test.name

    name                = "AllowAccessToAzureServices"
    server_name         = azurerm_sql_server.test[0].name
    start_ip_address    = "0.0.0.0"
    end_ip_address      = "0.0.0.0"
}

webapp / main.tf

resource "azurerm_sql_database" "test" {
    count = var.enable_db ? 1 : 0

    location            = var.location
    resource_group_name = var.resource_group_name
    server_name         = var.dbs_name

    name                             = var.project_name
    requested_service_objective_name = var.db_sku_size
}

main. tf

module "infrastructure" {
    source = "./infrastructure"

    project_name = "infra"

    enable_dbs         = true
    dbs_admin_login    = "someusername"
    dbs_admin_password = "somepassword"
}

module "my_webapp" {
    source = "./webapp"

    location            = module.infrastructure.location
    resource_group_name = module.infrastructure.resource_group_name
    project_name        = local.project_name

    enable_db                       = true
    dbs_name                        = module.infrastructure.dbs_name
    dbs_admin_login                 = module.infrastructure.dbs_admin_login
    dbs_admin_password              = module.infrastructure.dbs_admin_password
}

Если весь сценарий применен с использованием terraform apply, то все в порядке.

Но если следует применять только module.my_webapp с использованием terraform apply -target module.my_webapp, правило брандмауэра отсутствует, поскольку ононе является целью, и цель не требует ее напрямую. Тем не менее, правило необходимо и должно применяться каждый раз, когда применяется сам сервер базы данных.

Возможное «решение»:

Добавитьправила брандмауэра как выходные данные модуля infrastructure:

output "dbs_firewall_rules" {
    value = concat(
        azurerm_sql_firewall_rule.allow_azure_services,
        azurerm_sql_firewall_rule.allow_office_ip
    )
}

Затем добавьте эти выходные данные в качестве ввода в модуль webapp:

variable "dbs_firewall_rules" {
    description = "DB firewall rules required (used for the database in depends_on)"
    type        = list
}

и подключите его в основном сценарии:

module "my_webapp" {
    ...
    dbs_firewall_rules = module.infrastructure.dbs_firewall_rules
    ...
}

Недостаток: может быть только один тип ресурсовположить в список. Вот почему я переименовал его с dbs_dependencies на dbs_firewall_rules.

1 Ответ

0 голосов
/ 22 октября 2019

Если у вас есть правила брандмауэра, определенные в том же файле tf, что и SQL-сервер, они должны быть развернуты, потому что на сервер ссылаются, что правильно строит граф зависимостей. Я столкнулся с проблемами, когда он не работал специально с правилами брандмауэра SQL Server. В конечном итоге я использовал свойство depen_on для ресурса SQL Server, чтобы убедиться, что они всегда создаются. Это выглядит так:

resource "azurerm_sql_firewall_rule" "test" {
  name                = "FirewallRule1"
  resource_group_name = "${azurerm_resource_group.test.name}"
  server_name         = "${azurerm_sql_server.test.name}"
  start_ip_address    = "10.0.17.62"
  end_ip_address      = "10.0.17.62"
  depends_on = [azurerm_sql_server.test]
}

resource "azurerm_sql_server" "test" {
  name                         = "mysqlserver"
  resource_group_name          = "${azurerm_resource_group.test.name}"
  location                     = "${azurerm_resource_group.test.location}"
  version                      = "12.0"
  administrator_login          = "mradministrator"
  administrator_login_password = "thisIsDog11"

  tags = {
    environment = "production"
  }  
}

Затем просто добавьте к этому каждое правило, которое, как вы знаете, вы хотите. Если вы выполняете свои правила вне вашего модуля, то вы должны быть в состоянии сделать это аргументом, который вы можете передать ему, чтобы принудительно установить связь.

...