代码之家  ›  专栏  ›  技术社区  ›  mark

Terraform无法应用…运算符

  •  0
  • mark  · 技术社区  · 5 年前

    (我使用地形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 然后输出local。应用配置的结果是:

    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"
      }
    }
    

    但是用变量值替换“abc”,它就停止工作了:

    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

    因此,应该工作的代码(我改进了它- 价值观 不需要):

        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

    0 回复  |  直到 5 年前