Terraform не может применить оператор ... - PullRequest
1 голос
/ 05 февраля 2020

(я использую terraform 0.12.20)

В моем коде есть следующий фрагмент:

locals {
    x = merge(values({
        for location in local.locations: location => {
            for apsvc_name in var.apsvc_names: "${location}-${apsvc_name}" => {
                location = location
                apsvc_name = apsvc_name
            }
        }
    })...)

Затем выводится локальный x. Применение конфигурации приводит к:

Error: Invalid expanding argument value

  on ..\..\hosting-modules\web\app_hosting.tf line 35, in locals:
  35:     x = merge(values({
  36:         for location in local.locations: location => {
  37:             for apsvc_name in var.apsvc_names: "${location}-${apsvc_name}" => {
  38:                 location = location
  39:                 apsvc_name = apsvc_name
  40:             }
  41:         }
  42:     })...)

The expanding argument (indicated by ...) must be of a tuple, list, or set
type.

Теперь, если я обрежу вызов merge(...) и назначу результат values для x, результат будет выводиться просто отлично:

x = [
  {
    "centralus-backoffice" = {
      "apsvc_name" = "backoffice"
      "location" = "centralus"
    }
    "centralus-gateway" = {
      "apsvc_name" = "gateway"
      "location" = "centralus"
    }
    "centralus-javascriptclient" = {
      "apsvc_name" = "javascriptclient"
      "location" = "centralus"
    }
  },
  {
    "eastus2-backoffice" = {
      "apsvc_name" = "backoffice"
      "location" = "eastus2"
    }
    "eastus2-gateway" = {
      "apsvc_name" = "gateway"
      "location" = "eastus2"
    }
    "eastus2-javascriptclient" = {
      "apsvc_name" = "javascriptclient"
      "location" = "eastus2"
    }
  },
]

И это явно список, поэтому он должен соответствовать критериям ....

Чего мне не хватает?

РЕДАКТИРОВАТЬ 1

Замена местоположений списком времени компиляции работает:

locals {
    locations = ["abc", "xyz"]
    x = merge(values({
        for location in local.locations: location => {
            for apsvc_name in var.apsvc_names: "${location}-${apsvc_name}" => {
                location = location
                apsvc_name = apsvc_name
            }
        }
    })...)
}

Что приводит к:

Outputs:

x = {
  "abc-backoffice" = {
    "apsvc_name" = "backoffice"
    "location" = "abc"
  }
  "abc-gateway" = {
    "apsvc_name" = "gateway"
    "location" = "abc"
  }
  "abc-javascriptclient" = {
    "apsvc_name" = "javascriptclient"
    "location" = "abc"
  }
  "xyz-backoffice" = {
    "apsvc_name" = "backoffice"
    "location" = "xyz"
  }
  "xyz-gateway" = {
    "apsvc_name" = "gateway"
    "location" = "xyz"
  }
  "xyz-javascriptclient" = {
    "apsvc_name" = "javascriptclient"
    "location" = "xyz"
  }
}

Но замените "ab c" значением переменной, и оно перестанет работать:

locals {
    locations = [var.primary_location, "xyz"]
    x = merge(values({
        for location in local.locations: location => {
            for apsvc_name in var.apsvc_names: "${location}-${apsvc_name}" => {
                location = location
                apsvc_name = apsvc_name
            }
        }
    })...)
}

И удар:

Error: Invalid expanding argument value

  on ..\..\hosting-modules\web\app_hosting.tf line 5, in locals:
   5:     x = merge(values({
   6:         for location in local.locations: location => {
   7:             for apsvc_name in var.apsvc_names: "${location}-${apsvc_name}" => {
   8:                 location = location
   9:                 apsvc_name = apsvc_name
  10:             }
  11:         }
  12:     })...)
    |----------------
    | local.locations is tuple with 2 elements

The expanding argument (indicated by ...) must be of a tuple, list, or set
type.

РЕДАКТИРОВАТЬ 2

Итак, код, который должен работать (я его улучшил - values, это не требуется):

    merge([
        for location in local.locations: {
            for apsvc_name in var.apsvc_names: "${location}-${apsvc_name}" => {
                location = location
                apsvc_name = apsvc_name
            }
        }
    ]...)

не работает по таинственным причинам. Я получил следующий обходной путь:

    _y1 = [
        for location in local.locations: {
            for apsvc_name in var.apsvc_names: "${location}-${apsvc_name}" => {
                location = location
                apsvc_name = apsvc_name
            }
        }
    ]
    _y2 = flatten([for m in local._y1: [for k,v in m: { 
        key = k
        value = v
    }]])
    x = zipmap(local._y2.*.key, local._y2.*.value)

Тот, который работает.

РЕДАКТИРОВАТЬ 3

https://github.com/hashicorp/terraform/issues/24033

...