объединить две карты Terraform, только если условие истинно - PullRequest
2 голосов
/ 12 февраля 2020

Введение

Я хотел бы объединить две карты терраформ, только когда условие выполнено.

  • Объединение можно выполнить с помощью merge () функция.
  • Условием является наличие ключа на карте. Это можно проверить с помощью функции lookup () .
locals {
  # this merge is fine
  #
  workspace_default = "${
    merge(
      local.env["default"], 
      local.workspaces[terraform.workspace])}"

   # this merge fails with: "conditional operator cannot be used with list values"
   #
   # What I'd like for workspace is this conditional merge
   # based on wether local.env[terraform.workspace] exists. 
   #
    my_workspace = "${lookup(local.env, terraform.workspace, "") != "" ? 
      merge(local.workspace_default, local.env[terraform.workspace]) : 
      local.workspace_default}"

Справочная информация

Вы можете пропустить чтение, если вам все равно, почему я ' Я делаю условное слияние.

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

Я терраформирую тот же проект к нескольким рабочим местам. Рабочие пространства отличаются AWS учетными записями и регионами. Этот список определен в центральном файле terraform. Эта информация хранится вне каждого проекта, потому что:

  • многие проекты терраформированы во многие рабочие пространства,
  • файлы terraform проекта в управлении исходным кодом не нужно редактировать, если я позже я хочу терраформировать этот проект в новое рабочее пространство, которого не было, когда были записаны файлы терраформ проекта. Я предпочитаю добавлять новые рабочие пространства в один центральный файл terraform, чем в terraform каждого проекта. Файлы terraform проекта должны содержать информацию о том, какие ресурсы AWS необходимы (lambdas, динамо, роли и т. Д. c ..), но не о том, какая учетная запись AWS, последняя управляется вне проекта.

Центральный файл terraform выглядит как

locals {
  workspaces = {
    workspace_1 = {
       aws_region = us-east-1
       aws_account = [some account id]
    }
    workspace_2 = {
       aws_region = us-west-2
       aws_account = [some account id]
    }
    ...
    # a list of workspaces
  }
}

Информация о рабочем пространстве (aws account, region) может быть загружена с помощью простого слияния () в workspace_default. Пока все хорошо.

Теперь каждый проект может захотеть определить конкретную запись c локальной карты, возможно, этому проекту требуется более высокий RCU DynamoDB в рабочей области_17. Например,

locals {
   env = {
     # stuff that is common to this project in any workspace
     default = {
         rcu = [the normal RCU value]
         ...
         # list of key value pairs
     }
     # stuff that must be defined for this project in workspace_17
     workspace_17 {
         rcu = [a higher RCU value]
     }
   }
}

Я пытаюсь выяснить, как объединить переопределения рабочей области этого проекта в my_workspace. И проект не может ничего переопределить, поэтому locals.env[terraform.workspace] может не существовать. Следовательно, используется функция lookup().

Версия Terraform

Я использую версию Terraform 1.11.13 и не могу легко перейти на 1.12, поэтому любое решение должно работать с 1.11.

1 Ответ

1 голос
/ 12 февраля 2020

Следующее делает условное слияние

locals {
  workspace = "${
    merge(
      local.workspaces[terraform.workspace],
      merge(
        local.env["default"],
        local.env[contains(keys(local.env), terraform.workspace) ? terraform.workspace : "default"]))}"
}

...