5

我遇到了 Terraform EKS 标记问题,并且似乎没有找到可行的解决方案来在创建新集群时标记所有 VPC 子网。

提供一些上下文:我们有一个 AWS VPC,我们在其中将多个 EKS 集群部署到子网中。我们不创建 VPC 或子网是 EKS 集群创建的一部分。因此,创建集群的 terraform 代码不会标记现有子网和 VPC。虽然 EKS 会添加所需的标签,但下次我们在 VPC 上运行 terraform apply 时它们会自动删除。

我的解决方法是在 VPC 中提供一个 terraform.tfvars 文件,如下所示:

eks_tags = 
 [
 "kubernetes.io/cluster/${var.cluster-1}", "shared", 
 "kubernetes.io/cluster/${var.cluster-2}", "shared",
 "kubernetes.io/cluster/${var.cluster-2}", "shared",
]    

然后在 VPC 和子网资源中,我们执行类似的操作

    resource "aws_vpc" "demo" {
      cidr_block = "10.0.0.0/16"

      tags = "${
        map(
         ${var.eks_tags}
        )
     }"
    }

但是,上述方法似乎不起作用。我已经尝试了来自https://www.terraform.io/docs/configuration-0-11/interpolation.html的各种 Terraform 0.11 功能,但其中没有帮助。

有没有人能够解决这个问题?

我们总是为每个 EKS 集群创建新的 VPC 和子网的想法是错误的。显然,这必须是一种使用 Terraform 标记现有 VPC 和子网资源的方法吗?

4

3 回答 3

10

您现在可以使用 aws 提供程序ignore_tags属性,以便在aws_ec2_tag下次应用 VPC 模块时不会删除使用资源制作的标签。

例如提供者变为:

provider "aws" {
  profile = "terraform"
  region  = "us-west-1"
  
  // This is necessary so that tags required for eks can be applied to the vpc without changes to the vpc wiping them out.
  // https://registry.terraform.io/providers/hashicorp/aws/latest/docs/guides/resource-tagging
  ignore_tags {
    key_prefixes = ["kubernetes.io/"]
  }
}

然后,您可以在 EKS 模块中像这样利用aws_ec2_tag资源,而不必担心下次应用 VPC 模块时标签会被删除。

/*
  Start of resource tagging logic to update the provided vpc and its subnets with the necessary tags for eks to work
  The toset() function is actually multiplexing the resource block, one for every item in the set. It is what allows 
  for setting a tag on each of the subnets in the vpc.
*/
resource "aws_ec2_tag" "vpc_tag" {
  resource_id = data.terraform_remote_state.vpc.outputs.vpc_id
  key         = "kubernetes.io/cluster/${var.cluster_name}"
  value       = "shared"
}

resource "aws_ec2_tag" "private_subnet_tag" {
  for_each    = toset(data.terraform_remote_state.vpc.outputs.private_subnets)
  resource_id = each.value
  key         = "kubernetes.io/role/elb"
  value       = "1"
}

resource "aws_ec2_tag" "private_subnet_cluster_tag" {
  for_each    = toset(data.terraform_remote_state.vpc.outputs.private_subnets)
  resource_id = each.value
  key         = "kubernetes.io/cluster/${var.cluster_name}"
  value       = "shared"
}

resource "aws_ec2_tag" "public_subnet_tag" {
  for_each    = toset(data.terraform_remote_state.vpc.outputs.public_subnets)
  resource_id = each.value
  key         = "kubernetes.io/role/elb"
  value       = "1"
}

resource "aws_ec2_tag" "public_subnet_cluster_tag" {
  for_each    = toset(data.terraform_remote_state.vpc.outputs.public_subnets)
  resource_id = each.value
  key         = "kubernetes.io/cluster/${var.cluster_name}"
  value       = "shared"
}
于 2020-11-21T01:05:43.343 回答
1

在我们的例子中,我们有单独的脚本来配置 VPC 和网络资源,我们没有添加 EKS 特定标签。

对于 EKS 集群配置,我们有单独的脚本,它们将在集群上自动更新/添加标签。

因此,在 provider.tf 文件中的 VPC 脚本上,我们添加了以下条件,以便脚本不会删除这些标签并且一切正常。

provider "aws" {
region = "us-east-1"
 ignore_tags {
    key_prefixes = ["kubernetes.io/cluster/"]
  }
}
于 2020-07-27T06:39:09.783 回答
1

当有 2 段具有不同状态文件的代码试图作用于同一资源时,此问题将始终存在。

解决此问题的一种方法是在每次应用 EKS terraform 代码时将 VPC 资源重新导入 VPC 状态文件。这也将导入您的标签。子网也是如此,但从长远来看,这是一个手动且繁琐的过程。

terraform import aws_vpc.test_vpc vpc-a01106c2

参考:https ://www.terraform.io/docs/providers/aws/r/vpc.html

干杯!

于 2019-08-14T19:28:20.503 回答