Terraform:从模块中提取标签值

Terraform: pulling tag values from modules

我有一个标签模块,我想从中查找 terraform 0.13.2 中资源的值

tags.tf

    module "tags" {
      source             = "git::ssh://git@blah.git?ref=v0.2.3"
      product            = var.product
      tag3               = var.tag3
      tag4               = var.tag4
      tag5               = var.tag5
      tag6               = var.tag6
      tag7               = "tag7"
      tag8               = "tag8"
      tag9               = "tag9"
      tag10              = "tag10"
      componentInfo      = "componentinfo"
    }

app.tf

  tags = {
      source        = lookup(module.tags.tags,"source")
      componentInfo = lookup(module.tags.tags,"componentInfo") 
  }

然而,当我 运行 我得到:

    10:39:06        Error: Invalid function argument
    10:39:06        
    10:39:06        
    10:39:06        Warning: Value for undeclared variable
    10:39:06        
    10:39:06        The root module does not declare a variable named "aws_env" but a value was
    10:39:06        found in file "vars/egdp-dev-us-east-1.tfvars". To use this value, add a
    10:39:06        "variable" block to the configuration.
    10:39:06        
    10:39:06        Using a variables file to set an undeclared variable is deprecated and will
    10:39:06        become an error in a future release. If you wish to provide certain "global"
    10:39:06        settings to all configurations in your organization, use TF_VAR_...
    10:39:06        environment variables to set these instead.
    10:39:06        
    10:39:06        
    10:39:06        Warning: Deprecated Resource
    10:39:06        
    10:39:06        The null_data_source was historically used to construct intermediate values to
    10:39:06        re-use elsewhere in configuration, the same can now be achieved using locals
    10:39:06        
    10:39:06          on avro-gen-layer.tf line 30, in resource "aws_s3_bucket_object" "avro-gen-bucket":
    10:39:06          30:       source        = lookup(module.tags.tags,"source")
    10:39:06            |----------------
    10:39:06            | module.tags.tags is object with 16 attributes
    10:39:06        
    10:39:06        Invalid value for "inputMap" parameter: the given object has no attribute
    10:39:06        "source".

我在 github 运行ning terraform 版本 0.12.3 的其他地方看到过相同的代码模式。为了简洁起见,我删减了示例。

以下作品;但是,为我尝试配置的 s3 存储桶定义的标签太多,所以我想将其过滤为仅最重要的标签:

  tags = merge(
    module.tags.tags,
    {
        "Name" = "datahub_producer_td"
    }
  )

如有任何帮助,我们将不胜感激。

更新

我错过了源是一个有自己的输出的 terraform 模块。 Source 不是这些输出之一,因此第一次查找不会起作用,因为它不是输出,但似乎 componentInfo 应该有但得到了同样的错误。

这是该模块的 output.tf。

output.tf

    data "null_data_source" "tags" {
      count = length(keys(local.all_tags))
    
      inputs = {
        key                 = element(keys(local.all_tags), count.index)
        value               = element(values(local.all_tags), count.index)
        propagate_at_launch = "true"
      }
    }
    
    output "tags" {
      value = local.all_tags
    }
    
    output "asg_tags" {
      value = data.null_data_source.asg_tags.*.outputs
    }

您将标签模块视为地图,因此应该使用 locals 来代替地图对象,如下所示:

locals {
  tags = {
    source  = "source"
    product = "product"
  }
}


# Example usages:

resource "a_resource" "my_resource" {
  lookup_tags = {
      source  = lookup(local.tags,"source")
      product = lookup(local.tags,"product") 
  }

  local_tags = local.tags

  merge_tags = merge(
    local.tags,
    {
        "Name" = "datahub_producer_td"
    }
  )
}

如果你确实需要使用一个模块,那么你应该有一个输出 returns 一个映射

output "tags" {
  value = {
    source  = "source"
    product = "product"
  }
}

好的,所以标签模块中的“来源”是而不是 - 就是这样,而且宾果游戏正是日志所说的内容:facepalm:。此外,"componentInfo" 的索引是 "ComponentInfo"...

如果我将这些属性移动到本地然后使用命令行控制台 terraform console 来探索变量,那么更容易看到发生了什么,果然 module.tags.tags 是一个具有 17 的对象属性就像它说的那样。

为了使它更紧凑一些,我寻找一种方法来做 python 所谓的“字典理解”,我发现 this

我无法找到如何将 if 子句用于属性过滤器;但是,我能够过滤列表,然后过滤属性:

tags = merge(
    module.tags.tags,
    {
        "Name" = local.artifact
    }
)
s3_keys = [for k in keys(local.tags):k if contains([
    "ComponentInfo"],k)]
s3_tags = {for k in local.s3_keys: k => local.tags[k]}

通过这种方式,可以搜索并 select 仅搜索特定对象所需的标记,因为并非所有对象都具有相同的标记要求。

当然,这项工作可能更适合标签模块。

此外,lookup(module.tags.tags,"ComponentInfo") 确实有效