使用环境变量作为本地块中公共标签的映射

Using an environment variable as a map for common tags in a locals block

我 运行 在尝试在 terraform 中自动执行标记过程时遇到了一个特定问题。我已经设置了一个环境变量,它本质上是我们将用于应用中提供的所有资源的所有标签的列表。看起来像这样...

export TF_VAR_taglist='{JiraEpic = "ETOS-56","AssignedResearcherPri" = "Isaac",AssignedResearcherSec = "Matt"}'

设置环境变量后,我在 variables.tf 文件中添加了一个名为“taglist”的变量,用于获取上述环境变量。看起来像这样...

variable "taglist"{}

最后,我有另一个 locals.tf 文件,我在其中设置了一个 common_tags 变量。像这样...

locals { common_tags ="${var.taglist}" }

当我应用 terraform 时,在尝试正确映射标签时构建失败。这是我收到的错误...

Error: Incorrect attribute value type

  on kube_master_worker_nodes_ec2.tf line 9, in resource "aws_instance" "master":
   9:   tags = local.common_tags
    |----------------
    | local.common_tags is "{JiraEpic = \"ETOS-56\",AssignedResearcherPri = \"Isaac \",AssignedResearcherSec = \"Matt\"}"

Inappropriate value for attribute "tags": map of string required.

然后我决定像这样在 variables.tf 文件中将变量的类型定义为 map(string variable "taglist"{ type = map(string) } 我曾希望这将使 terraform 将此变量识别为字符串映射而不仅仅是字符串文字,但我错了,这些是我在应用该定义时遇到的错误。

Error: Missing attribute separator

  on <value for var.taglist> line 1:
  (source code not available)

Expected a newline or comma to mark the beginning of the next attribute.


Error: No value for required variable

  on variables.tf line 11:
  11: variable "taglist"{

The root module input variable "taglist" is not set, and has no default value.
Use a -var or -var-file command line argument to provide a value for this
variable.

我真的很纠结于此,我觉得我已经接近了。谁能对此提供一些见解以及我应该如何解决它?

Terraform 使用变量的类型约束来决定如何解释其值的字符串表示形式。默认情况下,Terraform 将假定该值需要原始类型,例如字符串或数字,因为这是通过命令行或环境变量设置变量的最典型情况。

由于您的标签列表是一个列表,您需要 Terraform 将其解释为地图表达式而不是字符串。您可以通过告诉 Terraform 您期望哪种类型的值来告诉 Terraform 这样做:

variable "taglist" {
  type = map(string)
}

您可以在 Terraform 文档部分阅读更多相关信息 Complex-typed Values

然后您需要确保环境变量中的值是有效的 object expression 以避免语法错误。如果您从 shell 命令行设置环境变量,那么您需要注意 escaping/quoting 以确保 Terraform 将看到所有引号完好无损且没有任何额外元字符的值。

结果通常难以清晰阅读,这就是为什么 Terraform 文档建议使用 .tfvars 文件来设置复杂类型的变量,而不是 -var 命令行选项或环境变量.但是,由于您正在使用自动化,您可能会发现生成 .tfvars.json 文件更容易,它使用标准 JSON 格式,因此使用大多数编程语言中可用的 JSON 库更容易生成.这是您在问题中显示的值的 .tfvars.json 等效值:

{
  "taglist": {
    "JiraEpic": "ETOS-56",
    "AssignedResearcherPri": "Isaac",
    "AssignedResearcherSec": "Matt"
  }
}

请注意,主观上我发现拥有一个名称以 list 结尾的变量非常令人困惑,而它实际上需要一个映射。这个变量的一个更典型的名称就是 tags,但如果提及它的类型以便与其他变量区分开来有用,那么我建议改为 tag_map,以减少混淆。

我首先要感谢 Martin Atkins 让我想到在我的环境变量中使用冒号而不是等号,因为这是唯一的问题。该变量未正确表示为 JSON 对象,因此 terraform 将其解释为字符串。

我变了

export TF_VAR_taglist='{JiraEpic = "ETOS-56","AssignedResearcherPri" = "Isaac",AssignedResearcherSec = "Matt"}'

至此

export TF_VAR_taglist='{"JiraEpic":"ETOS-56","AssignedResearcherPri":"Isaac", "AssignedResearcherSec":"Matt"}'

这个构建现在像猫薄荷上的小猫一样咕噜咕噜。