Как совместно использовать переменные Terraform в рабочих пространствах / модулях? - PullRequest
1 голос
/ 16 января 2020

Рабочие пространства 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) для их организации?

enter image description here

1 Ответ

2 голосов
/ 17 января 2020

В 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 независимой c от способа получения этих учетных данных. Вы можете применить ту же конфигурацию Terraform локально (за пределами Terraform Cloud), используя интеграцию с Azure CLI auth, в то время как среда выполнения Terraform Cloud часто использует принципала обслуживания.

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

  • ARM_CLIENT_ID
  • ARM_TENANT_ID
  • ARM_SUBSCRIPTION_ID
  • ARM_CLIENT_SECRET

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...