【问题标题】:terraform overwrite tag value in sub modulesterraform 覆盖子模块中的标签值
【发布时间】:2021-03-12 09:17:35
【问题描述】:

我正在使用 terraform 模块并将一组 default_tags 传递给子模块以进行一致的标记。如下所示,优点是子模块继承父模块的标签,但也可以添加自己的标签。

但是,我还想做的是能够覆盖一些继承的标签值,尤其是“名称”。但我似乎无法完成这项工作。

在下面的示例中(使用 AWS 的 terraform 13.5)为任何标签指定的第一个值,例如根模块中的“scratch-test”级联到子模块,不能更改。所以 VPC 名称标签和子网名称标签都 = "scratch-test"。

如何覆盖子模块中的标签值?

# root variables.tf
variable "default_tags" {
    type = map
    default = {
        environment_type = "Dev Environment"
    }
} 


# root main.tf
provider "aws" {
    region = var.region
}

module "vpc" {
    source = "../../../../scratch/tags-pattern"
    vpc_name                = "scratch-test"
    public_subnets          = ["10.0.0.0/26"]

    default_tags = merge(map(
        "Name", "scratch-test"
    ), var.default_tags)
}

# ../../../../scratch/tags-pattern/main.tf
module "the_vpc" {
    source = "../../terraform/tf-lib/network/vpc"

    vpc_name = var.vpc_name
    vpc_cidr = "10.0.0.0/24"

    default_tags = merge(map(
        "Name", "scratch-test-vpc",
        "vpc_tag", "vpc"
    ), var.default_tags)
}

# Add a subnet
module "public_subnets" {
    source = "../../terraform/tf-lib/network/subnet"
    vpc_id                  = module.the_vpc.output_vpc_id
    subnets                 = var.public_subnets
    default_tags = merge(map(
        "Name", "scratch-test-subnet",
        "subnet_tag", "public"
    ), var.default_tags)
}
# tf-lib/network/vpc/main.tf
resource "aws_vpc" "vpc" {
    cidr_block = var.vpc_cidr
    enable_dns_support = true
    enable_dns_hostnames = true
    tags = merge(map(
        "module", "tf-lib/network/vpc"
    ), var.default_tags)
} 

每个模块的 variable.tf 文件包含以下语句:

variable "default_tags" {}

【问题讨论】:

  • 你也应该看看 aws provider default_tags

标签: tags terraform terraform-modules


【解决方案1】:

merge function 通过用参数序列中定义的后一个映射覆盖来设置优先级:

merge 接受任意数量的映射或对象,并返回一个映射或对象,其中包含来自所有参数的合并元素集。

如果多个给定的映射或对象定义了相同的键或属性,则参数序列中后面的那个优先。如果参数类型不匹配,则在应用合并规则后,生成的类型将是与属性类型结构匹配的对象。

因此,为了允许您覆盖默认标签,您可以先指定默认标签,如下所示:

# root variables.tf
variable "default_tags" {
    type = map
    default = {
        environment_type = "Dev Environment"
    }
} 


# root main.tf
provider "aws" {
    region = var.region
}

module "vpc" {
    source = "../../../../scratch/tags-pattern"
    vpc_name                = "scratch-test"
    public_subnets          = ["10.0.0.0/26"]

    default_tags = merge(var.default_tags, map(
        "Name", "scratch-test"
    ))
}

使用{} 映射语法而不是map function 也可能看起来更清晰:

# root main.tf
provider "aws" {
    region = var.region
}

module "vpc" {
    source = "../../../../scratch/tags-pattern"
    vpc_name                = "scratch-test"
    public_subnets          = ["10.0.0.0/26"]

    default_tags = merge(var.default_tags, {
      Name = "scratch-test",
    })
}

正如map 函数文档中所述,此函数已被弃用,最终将被删除:

此功能已弃用。 从 Terraform v0.12 开始,Terraform 语言具有使用{} 创建地图的内置语法 分隔符。请改用内置语法。 map 函数将是 在未来版本的 Terraform 中删除。

【讨论】:

  • 谢谢,太好了,您还可以添加更多标签!
【解决方案2】:

截至AWS Provider v3.38.0,这可以更简单地完成。见this announcement blog。这是您使用新提供程序实现的请求,没有tags 变量。

# root main.tf
provider "aws" {
  region = var.region
  default_tags {
    tags = {
      environment_type = "Dev Environment"
    }
  }
}

module "vpc" {
  source         = "../../../../scratch/tags-pattern"
  vpc_name       = "scratch-test"
  public_subnets = ["10.0.0.0/26"]
}

# ../../../../scratch/tags-pattern/main.tf
module "the_vpc" {
  source = "../../terraform/tf-lib/network/vpc"

  vpc_name = var.vpc_name
  vpc_cidr = "10.0.0.0/24"

}

# tf-lib/network/vpc/main.tf
resource "aws_vpc" "vpc" {
  cidr_block           = var.vpc_cidr
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name    = "scratch-test-vpc"
    module  = "tf-lib/network/vpc"
    vpc_tag = "vpc"
  }
}

这里是main documentation for default_tags

【讨论】:

    猜你喜欢
    • 2020-12-02
    • 2021-02-27
    • 2021-05-04
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    相关资源
    最近更新 更多