modules/terraform/aws/karpenter/main.tf (209 lines of code) (raw):
## THIS TO AUTHENTICATE TO ECR, DON'T CHANGE IT
## IF DEFAULT REGION IS ``, NO NEED TO SET ALIAS FOR THIS
## IT IS ONLY USED FOR KARPENTER INSTALLATION
terraform {
required_version = ">= 1.0.0, < 2.0.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = ">= 2.32"
}
helm = {
source = "hashicorp/helm"
version = ">= 2.15"
}
kubectl = {
source = "alekc/kubectl"
version = ">= 2.0.4"
}
}
}
provider "aws" {
region = "us-east-1"
alias = "virginia"
}
provider "aws" {
region = local.region
}
provider "kubernetes" {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
token = data.aws_eks_cluster_auth.this.token
}
provider "helm" {
kubernetes {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
token = data.aws_eks_cluster_auth.this.token
}
}
provider "kubectl" {
apply_retry_count = 10
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
load_config_file = false
token = data.aws_eks_cluster_auth.this.token
}
locals {
region = lookup(var.json_input, "region", "us-east-1")
run_id = lookup(var.json_input, "run_id", "123456")
cluster_name = substr("${var.karpenter_config.cluster_name}-${local.run_id}", 0, 25)
eks_cluster_version = var.karpenter_config.eks_cluster_version
vpc_cidr = var.karpenter_config.vpc_cidr
eks_managed_node_group = var.karpenter_config.eks_managed_node_group
karpenter_chart_version = var.karpenter_config.karpenter_chart_version
tags = {
"owner" = var.owner
"scenario" = "${var.scenario_type}-${var.scenario_name}"
"creation_time" = timestamp()
"deletion_due_time" = timeadd(timestamp(), var.deletion_delay)
"run_id" = local.run_id
}
azs = slice(data.aws_availability_zones.available.names, 0, 3)
}
data "aws_availability_zones" "available" {
filter {
name = "opt-in-status"
values = ["opt-in-not-required"]
}
}
data "aws_eks_cluster_auth" "this" {
name = module.eks.cluster_name
}
data "aws_ecrpublic_authorization_token" "token" {
provider = aws.virginia
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.13.0"
name = local.cluster_name
cidr = local.vpc_cidr
azs = local.azs
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)]
private_subnets = ["10.0.32.0/19", "10.0.64.0/19", "10.0.96.0/19"]
create_igw = true
enable_nat_gateway = true
single_nat_gateway = true
enable_dns_hostnames = true
enable_dns_support = true
map_public_ip_on_launch = true
# Manage so we can name
manage_default_network_acl = true
default_network_acl_tags = { Name = "${local.cluster_name}-default" }
manage_default_route_table = true
default_route_table_tags = { Name = "${local.cluster_name}-default" }
manage_default_security_group = true
default_security_group_tags = { Name = "${local.cluster_name}-default" }
public_subnet_tags = {
"kubernetes.io/cluster/${local.cluster_name}" = "shared"
}
private_subnet_tags = {
"kubernetes.io/cluster/${local.cluster_name}" = "shared"
"karpenter.sh/discovery" = local.cluster_name
}
tags = local.tags
}
###############################################################################
# EKS Cluster
###############################################################################
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "20.24.0"
cluster_name = local.cluster_name
cluster_version = local.eks_cluster_version
cluster_endpoint_public_access = true
cluster_addons = {
kube-proxy = { most_recent = true }
coredns = { most_recent = true }
vpc-cni = {
most_recent = true
before_compute = true
configuration_values = jsonencode({
env = {
ENABLE_PREFIX_DELEGATION = "true"
WARM_PREFIX_TARGET = "1"
}
})
}
}
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
create_cloudwatch_log_group = false
create_cluster_security_group = false
create_node_security_group = false
authentication_mode = "API_AND_CONFIG_MAP"
enable_cluster_creator_admin_permissions = true
eks_managed_node_groups = {
managed_nodes = {
node_group_name = local.eks_managed_node_group.name
instance_types = local.eks_managed_node_group.instance_types
capacity_type = local.eks_managed_node_group.capacity_type
create_security_group = false
subnet_ids = module.vpc.private_subnets
max_size = local.eks_managed_node_group.max_size
desired_size = local.eks_managed_node_group.desired_size
min_size = local.eks_managed_node_group.min_size
# Launch template configuration
create_launch_template = true # false will use the default launch template
labels = {
intent = "control-apps"
}
}
}
tags = merge(local.tags, {
"karpenter.sh/discovery" = local.cluster_name
})
depends_on = [
module.vpc.vpc_id
]
}
module "eks_blueprints_addons" {
source = "aws-ia/eks-blueprints-addons/aws"
version = "1.16.3"
cluster_name = module.eks.cluster_name
cluster_endpoint = module.eks.cluster_endpoint
cluster_version = module.eks.cluster_version
oidc_provider_arn = module.eks.oidc_provider_arn
create_delay_dependencies = [for prof in module.eks.eks_managed_node_groups : prof.node_group_arn]
enable_aws_load_balancer_controller = false
enable_metrics_server = false
eks_addons = {
}
# Enable Karpenter for node autoscaling
enable_karpenter = true
karpenter = {
chart_version = local.karpenter_chart_version
repository_username = data.aws_ecrpublic_authorization_token.token.user_name
repository_password = data.aws_ecrpublic_authorization_token.token.password
timeout = 600
}
karpenter_enable_spot_termination = true
karpenter_enable_instance_profile_creation = true
karpenter_node = {
iam_role_use_name_prefix = false
}
tags = local.tags
depends_on = [
module.eks.cluster_id
]
}
module "aws-auth" {
source = "terraform-aws-modules/eks/aws//modules/aws-auth"
version = ">= 20.24"
manage_aws_auth_configmap = true
aws_auth_roles = [
{
rolearn = module.eks_blueprints_addons.karpenter.node_iam_role_arn
username = "system:node:{{EC2PrivateDNSName}}"
groups = ["system:bootstrappers", "system:nodes"]
},
]
depends_on = [
module.eks.cluster_id
]
}
##############################################################################################
# Karpenter settings
# https://github.com/aws-samples/karpenter-blueprints/blob/main/cluster/terraform/karpenter.tf
##############################################################################################
resource "kubectl_manifest" "karpenter_default_ec2_node_class" {
yaml_body = templatefile("${path.module}/karpenter_default_ec2_node_class.tftpl", {
node_iam_role_name = module.eks_blueprints_addons.karpenter.node_iam_role_name
cluster_name = local.cluster_name
})
depends_on = [
module.eks.cluster_id,
module.eks_blueprints_addons.karpenter,
]
}