Понимая общие модули в terraform и команду destroy, как мне исключить общий модуль при уничтожении?

В настоящее время я пишу сценарии для некоторой новой инфраструктуры Azure в Terraform, и делаю это с использованием вложенных модулей, чтобы сделать управление и развертывание различных частей нашей инфраструктуры приятным и ограниченным.

Я создал модуль под названием global, который содержит несколько общих ресурсов (в основном, только группы ресурсов и разрешения Azure), а также некоторые поисковые запросы по лазурным объявлениям и текущую конфигурацию клиента. Кажется, что их размещение в центральном модуле имеет смысл, чтобы избежать повторного использования кода и гарантировать, что они обрабатываются единообразно на протяжении всего проекта.

Однако я заметил, что когда я запускаю terraform destroy из любого модуля, все объекты в глобальном модуле помечаются для уничтожения. Есть ли способ исключить вложенный модуль из процесса уничтожения?

Должен ли я действительно размещать создание ресурсов (которые являются исключительно группами ресурсов и разрешениями, применяемыми к этим группам ресурсов) в моем глобальном модуле в отдельном, не вложенном модуле, но затем использовать модуль данных для моего вложенного глобального модуля, чтобы посмотреть повысить их ценности и т. д.?

Пример кода для глобального модуля: -

data "azurerm_client_config" "current" {}

data "azurerm_subscription" "subscription_current" {}

data "azuread_group" "dba" {
  name = "DBAs"
}

data "azuread_group" "bi-developer" {
  name = "BIDevelopers"
}

## local variables

locals {
  subscription_name = substr(lower("${data.azurerm_subscription.subscription_current.display_name}"),0,4)
  tenant_id = data.azurerm_subscription.subscription_current.tenant_id
}

## Create resource group and add permission

resource "azurerm_resource_group" "data" {
  name     = "data"
  location = var.location

  tags = {
    owner       = "Data"
    environment = local.subscription_name
  }
}

resource "azurerm_role_assignment" "DBA_Data_Permission" {
    scope = azurerm_resource_group.data.id
    role_definition_name = var.permission_level
    principal_id = data.azuread_group.dba.id
}

resource "azurerm_resource_group" "key-vault" {
  name     = "key-vault"
  location = var.location

  tags = {
    owner       = "techops"
    environment = local.subscription_name
  }
}

## Output Locals

output "subscription_name" {
    value = local.subscription_name
}

output "tenant_id" {
    value = local.tenant_id
}

output "object_id" {
    value = data.azurerm_client_config.current.object_id
}

## Output Resource Groups

output "rg_data_id" {
    value = azurerm_resource_group.data.id
}

output "rg_data_name" {
    value = azurerm_resource_group.data.name
}

output "rg_key-vault_id" {
    value = azurerm_resource_group.key-vault.id
}

output "rg_key-vault_name" {
    value = azurerm_resource_group.key-vault.name
}

## Output Azure AD lookups

output "aad_dba_id" {
    value = data.azuread_group.dba.id
}

output "aad_dba_name" {
    value = data.azuread_group.dba.name
}

output "aad_bi-developer_id" {
    value = data.azuread_group.bi-developer.id
}

output "aad_data-science_id" {
    value = data.azuread_group.data-science.id
}

И пример использования в одном из моих вложенных модулей для создания ресурсов базы данных в этом случае: -

module "global" {
  source = "../global"
  permission_level = var.permission_level
  location = var.location
  prefix = var.prefix
}

resource "azurerm_sql_server" "dwh" {
  name                         = "${var.prefix}-dwh-${module.global.subscription_name}"
  resource_group_name          = module.global.rg_data_name
  location                     = var.location
  version                      = "12.0"
  administrator_login          = var.sql_login_name
  administrator_login_password = var.sql_login_password

  tags = {
    environment = module.global.subscription_name
    owner       = "Data"
    subscription = "${module.global.subscription_name}"
  }
}

resource "azurerm_sql_active_directory_administrator" "dwh" {
  server_name          = azurerm_sql_server.dwh.name
  resource_group_name = module.global.rg_data_name
  login               = module.global.aad_dba_name
  tenant_id           = module.global.tenant_id
  object_id           = module.global.aad_dba_id
}

resource "azurerm_mssql_elasticpool" "dwh-ep" {
  name                = "${var.prefix}-dwh-${module.global.subscription_name}"
  resource_group_name = module.global.rg_data_name
  location            = var.location
  server_name         = azurerm_sql_server.dwh.name
  max_size_gb         = 1000

  sku {
      name  = "GP_Gen5"
      tier  = "GeneralPurpose"
      family = "Gen5"
      capacity = 6
  }

  per_database_settings {
    min_capacity = 0.25
    max_capacity = 4
  }

  depends_on = [azurerm_sql_server.dwh,azurerm_sql_active_directory_administrator.dwh]
} 

Затем в отдельном модуле следующий код для создания хранилища ключей с повторным использованием некоторых выходных данных глобального модуля: -

module "global" {
  source = "../global"
  permission_level = var.permission_level
  location = var.location
  prefix = var.prefix
}

resource "azurerm_key_vault" "data" {
    name = "${var.prefix}-data-${module.global.subscription_name}"
    location = var.location
    resource_group_name = "${module.global.rg_key-vault_name}"
    enabled_for_disk_encryption = true
    tenant_id = module.global.tenant_id

    sku_name = "standard"

    tags = {
        environment = module.global.subscription_name
        owner = "data"
    }
}

resource "azurerm_key_vault_access_policy" "data-bi-developer" {
    key_vault_id = "${azurerm_key_vault.data.id}"
    tenant_id = module.global.tenant_id
    object_id = module.global.aad_bi-developer_id

    certificate_permissions = ["get","list"]
    key_permissions = ["get", "list"]
    secret_permissions = ["get", "list"]   
}

resource "azurerm_key_vault_access_policy" "data-admin" {
    key_vault_id = "${azurerm_key_vault.data.id}"
    tenant_id = module.global.tenant_id
    object_id = "${module.global.object_id}"

certificate_permissions = [
      "create",
      "delete",
      "deleteissuers",
      "get",
      "getissuers",
      "import",
      "list",
      "listissuers",
      "managecontacts",
      "manageissuers",
      "setissuers",
      "update",
    ]

    key_permissions = [
      "backup",
      "create",
      "decrypt",
      "delete",
      "encrypt",
      "get",
      "import",
      "list",
      "purge",
      "recover",
      "restore",
      "sign",
      "unwrapKey",
      "update",
      "verify",
      "wrapKey",
    ]

    secret_permissions = [
      "backup",
      "delete",
      "get",
      "list",
      "purge",
      "recover",
      "restore",
      "set",
    ]
}

person Matthew Darwin    schedule 02.01.2020    source источник


Ответы (1)


Хорошо, удалось решить эту проблему, по сути разделив глобальный модуль на три модуля; один для хранения ресурсов, которые вообще не создаются с помощью terraform, как поисковые запросы (например, подписка, лазурная реклама и т. д.), один для создания групп ресурсов и применения разрешений, а затем один, который является чисто модулем данных для чтения групп ресурсов другие модули.

person Matthew Darwin    schedule 02.01.2020