module "vpc" { # https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest source = "terraform-aws-modules/vpc/aws" version = "3.14.2" name = local.cluster_name cidr = "10.0.0.0/16" azs = ["eu-west-2a", "eu-west-2b", "eu-west-2c"] private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] enable_nat_gateway = true single_nat_gateway = true one_nat_gateway_per_az = false public_subnet_tags = { "kubernetes.io/cluster/${local.cluster_name}" = "shared" "kubernetes.io/role/elb" = 1 } private_subnet_tags = { "kubernetes.io/cluster/${local.cluster_name}" = "shared" "kubernetes.io/role/internal-elb" = 1 } } module "eks" { # https://registry.terraform.io/modules/terraform-aws-modules/eks/aws/latest source = "terraform-aws-modules/eks/aws" version = "18.29.0" cluster_name = local.cluster_name cluster_version = "1.22" vpc_id = module.vpc.vpc_id subnet_ids = module.vpc.private_subnets # Required for Karpenter role below enable_irsa = true node_security_group_additional_rules = { ingress_nodes_karpenter_port = { description = "Cluster API to Node group for Karpenter webhook" protocol = "tcp" from_port = 8443 to_port = 8443 type = "ingress" source_cluster_security_group = true } } node_security_group_tags = { # NOTE - if creating multiple security groups with this module, only tag the # security group that Karpenter should utilize with the following tag # (i.e. - at most, only one security group should have this tag in your account) "karpenter.sh/discovery/${local.cluster_name}" = local.cluster_name } # Only need one node to get Karpenter up and running. # This ensures core services such as VPC CNI, CoreDNS, etc. are up and running # so that Karpenter can be deployed and start managing compute capacity as required eks_managed_node_groups = { initial = { instance_types = ["m5.large"] # Not required nor used - avoid tagging two security groups with same tag as well create_security_group = false # Ensure enough capacity to run 2 Karpenter pods min_size = 2 max_size = 3 desired_size = 2 iam_role_additional_policies = [ # Required by Karpenter "arn:${local.partition}:iam::aws:policy/AmazonSSMManagedInstanceCore" ] tags = { # This will tag the launch template created for use by Karpenter "karpenter.sh/discovery/${local.cluster_name}" = local.cluster_name } } } } resource "aws_iam_instance_profile" "karpenter" { name = "KarpenterNodeInstanceProfile-${local.cluster_name}" role = module.eks.eks_managed_node_groups["initial"].iam_role_name } module "karpenter_irsa" { source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" version = "5.3.1" role_name = "karpenter-controller-${local.cluster_name}" attach_karpenter_controller_policy = true karpenter_tag_key = "karpenter.sh/discovery/${local.cluster_name}" karpenter_controller_cluster_id = module.eks.cluster_id karpenter_controller_node_iam_role_arns = [ module.eks.eks_managed_node_groups["initial"].iam_role_arn ] oidc_providers = { ex = { provider_arn = module.eks.oidc_provider_arn namespace_service_accounts = ["karpenter:karpenter"] } } }