Terraform EKS 标记

Posted

技术标签:

【中文标题】Terraform EKS 标记【英文标题】:Terraform EKS tagging 【发布时间】:2019-12-21 01:31:11 【问题描述】:

我遇到了 问题,并且似乎找不到可行的解决方案来在创建新集群时标记所有 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 和子网资源的方法?

【问题讨论】:

【参考方案1】:

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

例如提供者变成:

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"

【讨论】:

确实非常有用。只能使用 count 代替,因为 for_each 总是抱怨“在应用之前无法确定的资源属性”。【参考方案2】:

当有 2 段具有不同状态文件的代码尝试对同一资源进行操作时,此问题将始终存在。

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

terraform import aws_vpc.test_vpc vpc-a01106c2

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

干杯!

【讨论】:

@praven.chandran 有那么一会儿,我认为上面的方法会起作用。但是,我的麻烦是我的子网资源是在一个模块中创建的,而 Terraform 需要在根模块中定义(见下文): terraform import aws_subnet.public-cluster-c-subnet subnet-02ed*****1b6b Error: resource address "aws_subnet.public-cluster-c-subnet" does not exist in the configuration. Before importing this resource, please create its configuration in the root module. For example: resource "aws_subnet" "public-cluster-c-subnet" # (resource arguments) 如果资源在模块内,您仍然可以导入它。尝试从状态文件中找到资源的绝对路径。类似:terraform import module.some_module.module.some_other_module.aws_vpc.test_vpc vpc-12341234 资源路径也应该在terraform plan的输出中可见。【参考方案3】:

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

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

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

provider "aws" 
region = "us-east-1"
 ignore_tags 
    key_prefixes = ["kubernetes.io/cluster/"]
  

【讨论】:

以上是关于Terraform EKS 标记的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Terraform 配置 AWS EKS 自动扩缩器?

使用 Terraform 将 `configMap` 应用到 EKS 集群

在 EKS 上,我如何验证我通过 Terraform 配置了 Spot 实例

Terraform 外部数据源 EKS 指纹有时不起作用

Terraform:尝试销毁 EKS 集群时出现“错误:删除 S3 存储桶时出错”

Terraform EKS 配置图被禁止