如何在Terraform中为EKS集群的两个节点组共用同一IAM角色?
背景
正在为EKS集群的多个节点组配置Fluent Bit以收集Pod日志,需要给每个节点组分配带必要权限的IAM角色,让Fluent Bit DaemonSet能将日志发送到CloudWatch日志组。
已尝试操作
- 最初通过在
eks_managed_node_groups中为每个节点组单独配置IAM角色(开启create_iam_role=true并设置不同命名),此方法可行,但希望通过Helm配置Fluent Bit时只使用一个节点IAM角色。 - 改用
eks_managed_node_group_defaults属性配置统一的IAM角色,让两个节点组共用,代码如下:
module "eks" { source = "terraform-aws-modules/eks/aws" version = "18.26.6" cluster_name = local.cluster_name cluster_version = "1.21" vpc_id = module.vpc.vpc_id subnet_ids = module.vpc.private_subnets eks_managed_node_group_defaults = { ami_type = "AL2_x86_64" attach_cluster_primary_security_group = true # 禁用自动创建安全组,使用外部提供的安全组 create_security_group = false # Fluent Bit 所需IAM角色配置 create_iam_role = true iam_role_name = "fluent-bit-logger" iam_role_use_name_prefix = false iam_role_description = "Fluent-bit-logging - default for node groups" iam_role_tags = { Name = "fb-ng-default" } } # 两个节点组配置(此处省略其他默认继承的属性) eks_managed_node_groups = { one = {} two = {} } }
预期结果
EKS集群模块执行成功,两个节点组共用同一个IAM角色。
报错信息
Error: failed creating IAM Role (fluent-bit-logger): EntityAlreadyExists: Role with name fluent-bit-logger already exists.
│ status code: 409, request id: fx11xxax-axex-4xxx-b749-09xx8x8xx17x
│
│ with module.eks-cluster.module.eks.module.eks_managed_node_group["two"].aws_iam_role.this[0],
│ on .terraform/modules/eks-cluster.eks/modules/eks-managed-node-group/main.tf line 431, in resource "aws_iam_role" "this":
│ 431: resource "aws_iam_role" "this" {
解决方法
问题根源在于使用eks_managed_node_group_defaults时,每个节点组都会根据默认配置尝试创建同名的IAM角色,导致重复创建冲突。正确做法是单独创建一个IAM角色,然后在每个节点组中引用该角色,而非让节点组自动创建:
- 先单独定义IAM角色及所需的Fluent Bit权限策略:
# 创建Fluent Bit所需IAM角色 resource "aws_iam_role" "fluent_bit_logger" { name = "fluent-bit-logger" description = "Fluent-bit-logging for EKS node groups" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "ec2.amazonaws.com" } } ] }) tags = { Name = "fb-ng-default" } } # 附加CloudWatch日志写入等必要权限策略(根据实际需求调整权限范围) resource "aws_iam_role_policy_attachment" "fluent_bit_cloudwatch" { role = aws_iam_role.fluent_bit_logger.name policy_arn = "arn:aws:iam::aws:policy/AmazonCloudWatchFullAccess" }
- 在EKS模块配置中,关闭节点组的自动IAM角色创建,引用上述已创建的角色:
module "eks" { source = "terraform-aws-modules/eks/aws" version = "18.26.6" cluster_name = local.cluster_name cluster_version = "1.21" vpc_id = module.vpc.vpc_id subnet_ids = module.vpc.private_subnets eks_managed_node_group_defaults = { ami_type = "AL2_x86_64" attach_cluster_primary_security_group = true create_security_group = false # 关闭自动创建IAM角色,使用外部角色 create_iam_role = false } eks_managed_node_groups = { one = { iam_role_arn = aws_iam_role.fluent_bit_logger.arn } two = { iam_role_arn = aws_iam_role.fluent_bit_logger.arn } } }
这样两个节点组会共用同一个预先创建的IAM角色,避免重复创建的冲突,同时满足Fluent Bit的权限需求。
内容的提问来源于stack exchange,提问作者Vishak Arudhra

