terraform 覆盖子模块中的标签值
terraform overwrite tag value in sub modules
我正在使用 terraform 模块并将一组 default_tags 传递给子模块以实现一致的标记。这如下所示,其优点是子模块继承了父模块的标签,但也可以添加自己的标签。
但是我还想做的是能够覆盖一些继承的标签值,尤其是“名称”。但我似乎无法完成这项工作。
在下面的示例中(使用 AWS 的 terraform 13.5)为任何标签指定的第一个值,例如根模块中的“scratch-test”向下级联到子模块,无法更改。所以 VPC Name tag 和 subnet Name tag = "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" {}
merge
function 通过覆盖参数序列中定义的后面的映射来设置优先级:
merge
takes an arbitrary number of maps or objects, and returns a single map or object that contains a merged set of elements from all arguments.
If more than one given map or object defines the same key or attribute, then the one that is later in the argument sequence takes precedence. If the argument types do not match, the resulting type will be an object matching the type structure of the attributes after the merging rules have been applied.
因此,为了允许您覆盖默认标签,您可以先指定默认标签,如下所示:
# 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
函数文档中所述,此函数已弃用,最终将被删除:
This function is deprecated. From Terraform v0.12, the Terraform
language has built-in syntax for creating maps using the {
and }
delimiters. Use the built-in syntax instead. The map
function will be
removed in a future version of Terraform.
截至 AWS Provider v3.38.0, this can be done more simply. See 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"
}
}
我正在使用 terraform 模块并将一组 default_tags 传递给子模块以实现一致的标记。这如下所示,其优点是子模块继承了父模块的标签,但也可以添加自己的标签。
但是我还想做的是能够覆盖一些继承的标签值,尤其是“名称”。但我似乎无法完成这项工作。
在下面的示例中(使用 AWS 的 terraform 13.5)为任何标签指定的第一个值,例如根模块中的“scratch-test”向下级联到子模块,无法更改。所以 VPC Name tag 和 subnet Name tag = "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" {}
merge
function 通过覆盖参数序列中定义的后面的映射来设置优先级:
merge
takes an arbitrary number of maps or objects, and returns a single map or object that contains a merged set of elements from all arguments.If more than one given map or object defines the same key or attribute, then the one that is later in the argument sequence takes precedence. If the argument types do not match, the resulting type will be an object matching the type structure of the attributes after the merging rules have been applied.
因此,为了允许您覆盖默认标签,您可以先指定默认标签,如下所示:
# 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
函数文档中所述,此函数已弃用,最终将被删除:
This function is deprecated. From Terraform v0.12, the Terraform language has built-in syntax for creating maps using the
{
and}
delimiters. Use the built-in syntax instead. Themap
function will be removed in a future version of Terraform.
截至 AWS Provider v3.38.0, this can be done more simply. See 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"
}
}