Как разделить переменные Terraform между рабочими пространствами / модулями?

Рабочие области Terraform Cloud позволяют мне определять переменные, но я не могу найти способ поделиться переменными более чем в одной рабочей области.

В моем примере у меня есть, скажем, два рабочих пространства:

  • База данных
  • заявка

В обоих случаях я буду использовать одни и те же учетные данные AzureRM для подключения. Ниже приведены общие значения, используемые рабочими областями для подключения к моей подписке Azure:

provider "azurerm" {
  subscription_id = "00000000-0000-0000-0000-000000000000"
  client_id       = "00000000-0000-0000-0000-000000000000"
  client_secret   = "00000000000000000000000000000000"
  tenant_id       = "00000000-0000-0000-0000-000000000000"
}

Не имеет смысла дублировать значения (в моем случае у меня будет, наверное, 10 рабочих пространств). Есть ли способ сделать это?

Или правильный подход - определить "базу данных" и "приложение" как модуль, а затем использовать рабочие области (DEV, QA, PROD) для их оркестровки?

2 ответа

Решение

В Terraform Cloud объект Workspace в настоящее время является наименее детализированным местом, где вы можете напрямую указать значения переменных. Нет встроенного механизма для обмена значениями переменных между рабочими областями.

Однако один из способов приблизиться к этому - управлять Terraform Cloud с помощью самого Terraform. Вtfeпровайдер (названный в честь Terraform Enterprise по историческим причинам, поскольку он был создан до запуска Terraform Cloud) позволит Terraform управлять рабочими пространствами Terraform Cloud и связанными с ними переменными.

variable "workspaces" {
  type = set(string)
}

variable "common_environment_variables" {
  type = map(string)
}

provider "tfe" {
  hostname = "app.terraform.io" # Terraform Cloud
}

resource "tfe_workspace" "example" {
  for_each = var.workspaces

  organization = "your-organization-name"
  name         = each.key
}

resource "tfe_variable" "example" {
  # We'll need one tfe_variable instance for each
  # combination of workspace and environment variable,
  # so this one has a more complicated for_each expression.
  for_each = {
    for pair in setproduct(var.workspaces, keys(var.common_environment_variables)) : "${pair[0]}/${pair[1]}" => {
      workspace_name = pair[0]
      workspace_id   = tfe_workspace.example[pair[0]].id
      name           = pair[1]
      value          = var.common_environment_variables[pair[1]]
    }
  }

  workspace_id = each.value.workspace_id

  category  = "env"
  key       = each.value.name
  value     = each.value.value
  sensitive = true
}

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


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

Поэтому, чтобы предоставить учетные данные в среде Terraform Cloud, вы должны поместить следующие переменные среды в var.common_environment_variables:

  • ARM_CLIENT_ID
  • ARM_TENANT_ID
  • ARM_SUBSCRIPTION_ID
  • ARM_CLIENT_SECRET

Если вы используете само Terraform Cloud для выполнения операций в этом рабочем пространстве, управляя Terraform Cloud (естественно, вам нужно будет настроить его вручную для начальной загрузки, а не самоуправления), вы можете настроить var.common_environment_variables в качестве чувствительной переменной в этой рабочей области.

Если вы вместо этого установите его через переменные Terraform, переданные в provider "azurerm" block (как вы указали в своем примере), то вы заставляете любого человека или систему, выполняющую конфигурацию, напрямую заполнять эти переменные, заставляя их использовать принципала службы вместо одного из других механизмов и предотвращая автоматическое получение Terraform учетных данных, установленных с использованием az login. Конфигурация Terraform, как правило, должна описывать только то, чем управляет Terraform, а не параметры, связанные с тем, кто запускает Terraform или где запускается Terraform.

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

Теперь вы можете использовать наборы переменных для повторного использования переменных в нескольких рабочих областях.

Другие вопросы по тегам