Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
220 changes: 220 additions & 0 deletions eks/terraform/modules/cluster/irsa.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
################################################################################
# IRSA v1
################################################################################

data "tls_certificate" "eks_oidc_issuer" {
url = aws_eks_cluster.cluster.identity[0].oidc[0].issuer
}

resource "aws_iam_openid_connect_provider" "cluster" {
count = var.use_irsa_v1 ? 1 : 0
client_id_list = ["sts.amazonaws.com"]
thumbprint_list = [data.tls_certificate.eks_oidc_issuer.certificates[0].sha1_fingerprint]
url = aws_eks_cluster.cluster.identity[0].oidc[0].issuer
}

moved {
from = aws_iam_openid_connect_provider.cluster
to = aws_iam_openid_connect_provider.cluster[0]
}

module "cluster_autoscaler_irsa_role" {
count = var.use_irsa_v1 ? 1 : 0

source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
version = "5.34.0"

role_name = "${var.cluster_name}-cluster-autoscaler"
policy_name_prefix = "${var.cluster_name}-"

attach_cluster_autoscaler_policy = true
cluster_autoscaler_cluster_ids = [aws_eks_cluster.cluster.id]

oidc_providers = {
main = {
provider_arn = aws_iam_openid_connect_provider.cluster[0].arn
namespace_service_accounts = ["kube-system:${local.cluster_autoscaler_service_account}"]
}
}
}

moved {
from = module.cluster_autoscaler_irsa_role
to = module.cluster_autoscaler_irsa_role[0]
}


module "loadbalancer_controller_irsa_role" {
count = var.use_irsa_v1 ? 1 : 0

source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
version = "5.34.0"

role_name = "${var.cluster_name}-loadbalancer-controller"
policy_name_prefix = "${var.cluster_name}-"

attach_load_balancer_controller_policy = true

oidc_providers = {
main = {
provider_arn = aws_iam_openid_connect_provider.cluster[0].arn
namespace_service_accounts = ["kube-system:${local.loadbalancer_controller_service_account}"]
}
}
}

moved {
from = module.loadbalancer_controller_irsa_role
to = module.loadbalancer_controller_irsa_role[0]
}

module "ebs_csi_irsa_role" {
count = var.use_irsa_v1 ? 1 : 0

source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
version = "5.34.0"

role_name = "${var.cluster_name}-ebs-csi"
policy_name_prefix = "${var.cluster_name}-"

attach_ebs_csi_policy = true

oidc_providers = {
main = {
provider_arn = aws_iam_openid_connect_provider.cluster[0].arn
namespace_service_accounts = ["kube-system:ebs-csi-controller-sa"]
}
}
}

moved {
from = module.ebs_csi_irsa_role
to = module.ebs_csi_irsa_role[0]
}

module "vpc_cni_irsa_role" {
count = var.use_irsa_v1 ? 1 : 0

source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
version = "5.34.0"

role_name = "${var.cluster_name}-vpc-cni"
policy_name_prefix = "${var.cluster_name}-"

attach_vpc_cni_policy = true
vpc_cni_enable_ipv4 = true

oidc_providers = {
main = {
provider_arn = aws_iam_openid_connect_provider.cluster[0].arn
namespace_service_accounts = ["kube-system:aws-node"]
}
}
}

moved {
from = module.vpc_cni_irsa_role
to = module.vpc_cni_irsa_role[0]
}

################################################################################
# IRSA v1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This header should say v2

################################################################################
module "cluster_autoscaler_pod_identity" {
count = var.use_irsa_v2 ? 1 : 0

source = "terraform-aws-modules/eks-pod-identity/aws"
version = "1.2.1"

name = "${var.cluster_name}-ca"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to also set use_name_prefix to false because by default it uses prefix to create all resources and the prefix is having length limit of 37. Hence, the deployment will fail for long datacenter name. I found the issue when I was testing the pod identity migration for existing cluster.


attach_cluster_autoscaler_policy = true
use_name_prefix = true
cluster_autoscaler_cluster_names = [aws_eks_cluster.cluster.id]

# Pod Identity Associations
association_defaults = {
namespace = local.contorllers_namespace
service_account = local.cluster_autoscaler_service_account
}

associations = {
cluster-autoscaler = {
cluster_name = aws_eks_cluster.cluster.id
}
}
}

module "aws_lb_controller_pod_identity" {
count = var.use_irsa_v2 ? 1 : 0

source = "terraform-aws-modules/eks-pod-identity/aws"
version = "1.2.1"

name = "${var.cluster_name}-lbc"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as before to use use_name_prefix


attach_aws_lb_controller_policy = true
use_name_prefix = true

# Pod Identity Associations
association_defaults = {
namespace = local.contorllers_namespace
service_account = local.loadbalancer_controller_service_account
}

associations = {
aws-lbc = {
cluster_name = aws_eks_cluster.cluster.id
}
}

}

module "aws_ebs_csi_pod_identity" {
count = var.use_irsa_v2 ? 1 : 0

source = "terraform-aws-modules/eks-pod-identity/aws"
version = "1.2.1"

name = "${var.cluster_name}-ebs-csi"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as before to use use_name_prefix


attach_aws_ebs_csi_policy = true
use_name_prefix = true

# Pod Identity Associations
association_defaults = {
namespace = local.contorllers_namespace
service_account = local.ebs_csi_controller_service_account
}

associations = {
ebs-csi = {
cluster_name = aws_eks_cluster.cluster.id
}
}
}

module "aws_vpc_cni_pod_identity" {
count = var.use_irsa_v2 ? 1 : 0

source = "terraform-aws-modules/eks-pod-identity/aws"
version = "1.2.1"

name = "${var.cluster_name}-vpc-cni"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as before to use use_name_prefix


attach_aws_vpc_cni_policy = true
aws_vpc_cni_enable_ipv4 = true
use_name_prefix = true

# Pod Identity Associations
association_defaults = {
namespace = local.contorllers_namespace
service_account = local.vpc_cni_service_account
}

associations = {
vpc-cni = {
cluster_name = aws_eks_cluster.cluster.id
}
}
}
123 changes: 29 additions & 94 deletions eks/terraform/modules/cluster/main.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
locals {
cluster_autoscaler_service_account = "cluster-autoscaler"
loadbalancer_controller_service_account = "aws-load-balancer-controller"
ebs_csi_controller_service_account = "ebs-csi-controller-sa"
vpc_cni_service_account = "aws-node"
contorllers_namespace = "kube-system"

default_instance_type = "m5.large"
prod1k_instance_type = "r5.large"
Expand All @@ -15,90 +18,6 @@ locals {
data "aws_partition" "current" {}
data "aws_caller_identity" "current" {}

################################################################################
# Cluster IAM
################################################################################

data "tls_certificate" "eks_oidc_issuer" {
url = aws_eks_cluster.cluster.identity[0].oidc[0].issuer
}

resource "aws_iam_openid_connect_provider" "cluster" {
client_id_list = ["sts.amazonaws.com"]
thumbprint_list = [data.tls_certificate.eks_oidc_issuer.certificates[0].sha1_fingerprint]
url = aws_eks_cluster.cluster.identity[0].oidc[0].issuer
}

module "cluster_autoscaler_irsa_role" {
source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
version = "5.34.0"

role_name = "${var.cluster_name}-cluster-autoscaler"
policy_name_prefix = "${var.cluster_name}-"

attach_cluster_autoscaler_policy = true
cluster_autoscaler_cluster_ids = [aws_eks_cluster.cluster.id]

oidc_providers = {
main = {
provider_arn = aws_iam_openid_connect_provider.cluster.arn
namespace_service_accounts = ["kube-system:${local.cluster_autoscaler_service_account}"]
}
}
}

module "loadbalancer_controller_irsa_role" {
source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
version = "5.34.0"

role_name = "${var.cluster_name}-loadbalancer-controller"
policy_name_prefix = "${var.cluster_name}-"

attach_load_balancer_controller_policy = true

oidc_providers = {
main = {
provider_arn = aws_iam_openid_connect_provider.cluster.arn
namespace_service_accounts = ["kube-system:${local.loadbalancer_controller_service_account}"]
}
}
}

module "ebs_csi_irsa_role" {
source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
version = "5.34.0"

role_name = "${var.cluster_name}-ebs-csi"
policy_name_prefix = "${var.cluster_name}-"

attach_ebs_csi_policy = true

oidc_providers = {
main = {
provider_arn = aws_iam_openid_connect_provider.cluster.arn
namespace_service_accounts = ["kube-system:ebs-csi-controller-sa"]
}
}
}

module "vpc_cni_irsa_role" {
source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
version = "5.34.0"

role_name = "${var.cluster_name}-vpc-cni"
policy_name_prefix = "${var.cluster_name}-"

attach_vpc_cni_policy = true
vpc_cni_enable_ipv4 = true

oidc_providers = {
main = {
provider_arn = aws_iam_openid_connect_provider.cluster.arn
namespace_service_accounts = ["kube-system:aws-node"]
}
}
}

resource "aws_iam_role" "cluster" {
name = "${var.cluster_name}-cluster"
description = "IAM role for the EKS cluster"
Expand Down Expand Up @@ -313,10 +232,16 @@ resource "aws_cloudwatch_log_group" "cluster_logs" {
# Add-ons
################################################################################

/*
* Due to a bug in the AWS provider, where service_account_role_arn can be removed from the addon after being added
* If user wants to switch to IRSA v1, they need to remove IAM role from the addon and reapply it manually so the changes will be applied
* Here's the github issue: https://github.com/hashicorp/terraform-provider-aws/issues/30645
*/

resource "aws_eks_addon" "csi-driver" {
cluster_name = aws_eks_cluster.cluster.name
addon_name = "aws-ebs-csi-driver"
service_account_role_arn = module.ebs_csi_irsa_role.iam_role_arn
service_account_role_arn = var.use_irsa_v1 ? module.ebs_csi_irsa_role.iam_role_arn : null

resolve_conflicts_on_create = "OVERWRITE"
resolve_conflicts_on_update = "PRESERVE"
Expand All @@ -335,7 +260,7 @@ resource "aws_eks_addon" "csi-driver" {
resource "aws_eks_addon" "vpc-cni" {
cluster_name = aws_eks_cluster.cluster.name
addon_name = "vpc-cni"
service_account_role_arn = module.vpc_cni_irsa_role.iam_role_arn
service_account_role_arn = var.use_irsa_v1 ? module.vpc_cni_irsa_role.iam_role_arn : null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Luay-Sol I recommend to also add addon_version argument here, otherwise it will use default version for the EKS cluster version.

The pod identity does not work if the vpc-cni version is earlier than 1.15.5-eksbuild.1. If we don't set the addon_version explicitly here, the default version for 1.27 for example, is v1.15.1-eksbuild.1 which is earlier than the required version.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nagsubhrajitt do you think it is required here. Considering 1.27 it is going to be out of regular support in couple day from now (July 24).

Another consideration is this project is supposed to be used for cluster creation of latest version of k8s/eks. So I don't see a situation or a reason for supporting older versions.

Reason I am on the fence about add-ons version hard coding: it is going to be challenging for us (as maintainers) for this project as well as for the users.


resolve_conflicts_on_create = "OVERWRITE"
resolve_conflicts_on_update = "PRESERVE"
Expand Down Expand Up @@ -372,6 +297,16 @@ resource "aws_eks_addon" "kube-proxy" {
]
}

resource "aws_eks_addon" "pod-identity" {
count = var.use_irsa_v2 ? 1 : 0

cluster_name = aws_eks_cluster.cluster.name
addon_name = "eks-pod-identity-agent"

resolve_conflicts_on_create = "OVERWRITE"
resolve_conflicts_on_update = "PRESERVE"
}

################################################################################
# Worker Node IAM
################################################################################
Expand Down Expand Up @@ -725,9 +660,9 @@ locals {
rbac : {
serviceAccount : {
name : local.cluster_autoscaler_service_account,
annotations : {
"eks.amazonaws.com/role-arn" : try(module.cluster_autoscaler_irsa_role.iam_role_arn, "")
}
annotations : try(var.use_irsa_v1 ? {
"eks.amazonaws.com/role-arn" : module.cluster_autoscaler_irsa_role[0].iam_role_arn
} : null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Luay-Sol I am not sure about the syntax but AFAIK the try function takes 2 arguments. I can see that you have made the first one but which one is the fallback expression? Am I missing anything here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not real, here's the definition of try:

try evaluates all of its argument expressions in turn and returns the result of the first one that does not produce any errors.

And below an example:

Screenshot 2024-07-18 at 9 16 10 PM

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So one expression with a result will work

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. However, if there is only one expression (so there is no fallback), can we not just use the expression?

}
}
})
Expand All @@ -736,10 +671,10 @@ locals {
clusterName : var.cluster_name,
serviceAccount : {
name : local.loadbalancer_controller_service_account,
annotations : {
"eks.amazonaws.com/role-arn" : try(module.loadbalancer_controller_irsa_role.iam_role_arn, "")
}
},
annotations : try(var.use_irsa_v1 ? {
"eks.amazonaws.com/role-arn" : module.loadbalancer_controller_irsa_role[0].iam_role_arn
} : null)
}
defaultTags : var.common_tags
})
}
}
Loading
Loading