provider "aws" { region = local.region } provider "kubernetes" { host = module.eks.cluster_endpoint cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data) exec { api_version = "client.authentication.k8s.io/v1beta1" command = "aws" # This requires the awscli to be installed locally where Terraform is executed args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name] } } data "aws_availability_zones" "available" {} data "aws_caller_identity" "current" {} locals { name = "ex-${replace(basename(path.cwd), "_", "-")}" region = "eu-west-1" vpc_cidr = "10.0.0.0/16" azs = slice(data.aws_availability_zones.available.names, 0, 3) tags = { Example = local.name GithubRepo = "terraform-aws-eks" GithubOrg = "terraform-aws-modules" } } ################################################################################ # EKS Module ################################################################################ module "eks" { source = "../.." cluster_name = local.name cluster_endpoint_public_access = true cluster_addons = { coredns = { preserve = true most_recent = true timeouts = { create = "25m" delete = "10m" } } kube-proxy = { most_recent = true } vpc-cni = { most_recent = true } } # External encryption key create_kms_key = false cluster_encryption_config = { resources = ["secrets"] provider_key_arn = module.kms.key_arn } iam_role_additional_policies = { additional = aws_iam_policy.additional.arn } vpc_id = module.vpc.vpc_id subnet_ids = module.vpc.private_subnets control_plane_subnet_ids = module.vpc.intra_subnets # Extend cluster security group rules cluster_security_group_additional_rules = { ingress_nodes_ephemeral_ports_tcp = { description = "Nodes on ephemeral ports" protocol = "tcp" from_port = 1025 to_port = 65535 type = "ingress" source_node_security_group = true } # Test: https://github.com/terraform-aws-modules/terraform-aws-eks/pull/2319 ingress_source_security_group_id = { description = "Ingress from another computed security group" protocol = "tcp" from_port = 22 to_port = 22 type = "ingress" source_security_group_id = aws_security_group.additional.id } } # Extend node-to-node security group rules node_security_group_additional_rules = { ingress_self_all = { description = "Node to node all ports/protocols" protocol = "-1" from_port = 0 to_port = 0 type = "ingress" self = true } # Test: https://github.com/terraform-aws-modules/terraform-aws-eks/pull/2319 ingress_source_security_group_id = { description = "Ingress from another computed security group" protocol = "tcp" from_port = 22 to_port = 22 type = "ingress" source_security_group_id = aws_security_group.additional.id } } # Self Managed Node Group(s) self_managed_node_group_defaults = { vpc_security_group_ids = [aws_security_group.additional.id] iam_role_additional_policies = { additional = aws_iam_policy.additional.arn } instance_refresh = { strategy = "Rolling" preferences = { min_healthy_percentage = 66 } } } self_managed_node_groups = { spot = { instance_type = "m5.large" instance_market_options = { market_type = "spot" } pre_bootstrap_user_data = <<-EOT echo "foo" export FOO=bar EOT bootstrap_extra_args = "--kubelet-extra-args '--node-labels=node.kubernetes.io/lifecycle=spot'" post_bootstrap_user_data = <<-EOT cd /tmp sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm sudo systemctl enable amazon-ssm-agent sudo systemctl start amazon-ssm-agent EOT } } # EKS Managed Node Group(s) eks_managed_node_group_defaults = { ami_type = "AL2_x86_64" instance_types = ["m6i.large", "m5.large", "m5n.large", "m5zn.large"] attach_cluster_primary_security_group = true vpc_security_group_ids = [aws_security_group.additional.id] iam_role_additional_policies = { additional = aws_iam_policy.additional.arn } } eks_managed_node_groups = { blue = {} green = { min_size = 1 max_size = 10 desired_size = 1 instance_types = ["t3.large"] capacity_type = "SPOT" labels = { Environment = "test" GithubRepo = "terraform-aws-eks" GithubOrg = "terraform-aws-modules" } taints = { dedicated = { key = "dedicated" value = "gpuGroup" effect = "NO_SCHEDULE" } } update_config = { max_unavailable_percentage = 33 # or set `max_unavailable` } tags = { ExtraTag = "example" } } } # Fargate Profile(s) fargate_profiles = { default = { name = "default" selectors = [ { namespace = "kube-system" labels = { k8s-app = "kube-dns" } }, { namespace = "default" } ] tags = { Owner = "test" } timeouts = { create = "20m" delete = "20m" } } } # Create a new cluster where both an identity provider and Fargate profile is created # will result in conflicts since only one can take place at a time # # OIDC Identity provider # cluster_identity_providers = { # sts = { # client_id = "sts.amazonaws.com" # } # } # aws-auth configmap manage_aws_auth_configmap = true aws_auth_node_iam_role_arns_non_windows = [ module.eks_managed_node_group.iam_role_arn, module.self_managed_node_group.iam_role_arn, ] aws_auth_fargate_profile_pod_execution_role_arns = [ module.fargate_profile.fargate_profile_pod_execution_role_arn ] aws_auth_roles = [ { rolearn = module.eks_managed_node_group.iam_role_arn username = "system:node:{{EC2PrivateDNSName}}" groups = [ "system:bootstrappers", "system:nodes", ] }, { rolearn = module.self_managed_node_group.iam_role_arn username = "system:node:{{EC2PrivateDNSName}}" groups = [ "system:bootstrappers", "system:nodes", ] }, { rolearn = module.fargate_profile.fargate_profile_pod_execution_role_arn username = "system:node:{{SessionName}}" groups = [ "system:bootstrappers", "system:nodes", "system:node-proxier", ] } ] aws_auth_users = [ { userarn = "arn:aws:iam::66666666666:user/user1" username = "user1" groups = ["system:masters"] }, { userarn = "arn:aws:iam::66666666666:user/user2" username = "user2" groups = ["system:masters"] }, ] aws_auth_accounts = [ "777777777777", "888888888888", ] tags = local.tags } ################################################################################ # Sub-Module Usage on Existing/Separate Cluster ################################################################################ module "eks_managed_node_group" { source = "../../modules/eks-managed-node-group" name = "separate-eks-mng" cluster_name = module.eks.cluster_name cluster_version = module.eks.cluster_version subnet_ids = module.vpc.private_subnets cluster_primary_security_group_id = module.eks.cluster_primary_security_group_id vpc_security_group_ids = [ module.eks.cluster_security_group_id, ] ami_type = "BOTTLEROCKET_x86_64" platform = "bottlerocket" # this will get added to what AWS provides bootstrap_extra_args = <<-EOT # extra args added [settings.kernel] lockdown = "integrity" [settings.kubernetes.node-labels] "label1" = "foo" "label2" = "bar" EOT tags = merge(local.tags, { Separate = "eks-managed-node-group" }) } module "self_managed_node_group" { source = "../../modules/self-managed-node-group" name = "separate-self-mng" cluster_name = module.eks.cluster_name cluster_version = module.eks.cluster_version cluster_endpoint = module.eks.cluster_endpoint cluster_auth_base64 = module.eks.cluster_certificate_authority_data instance_type = "m5.large" subnet_ids = module.vpc.private_subnets vpc_security_group_ids = [ module.eks.cluster_primary_security_group_id, module.eks.cluster_security_group_id, ] tags = merge(local.tags, { Separate = "self-managed-node-group" }) } module "fargate_profile" { source = "../../modules/fargate-profile" name = "separate-fargate-profile" cluster_name = module.eks.cluster_name subnet_ids = module.vpc.private_subnets selectors = [{ namespace = "kube-system" }] tags = merge(local.tags, { Separate = "fargate-profile" }) } ################################################################################ # Disabled creation ################################################################################ module "disabled_eks" { source = "../.." create = false } module "disabled_fargate_profile" { source = "../../modules/fargate-profile" create = false } module "disabled_eks_managed_node_group" { source = "../../modules/eks-managed-node-group" create = false } module "disabled_self_managed_node_group" { source = "../../modules/self-managed-node-group" create = false } ################################################################################ # Supporting resources ################################################################################ module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "~> 3.0" name = local.name cidr = local.vpc_cidr azs = local.azs private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)] public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)] intra_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 52)] enable_nat_gateway = true single_nat_gateway = true enable_dns_hostnames = true enable_flow_log = true create_flow_log_cloudwatch_iam_role = true create_flow_log_cloudwatch_log_group = true public_subnet_tags = { "kubernetes.io/role/elb" = 1 } private_subnet_tags = { "kubernetes.io/role/internal-elb" = 1 } tags = local.tags } resource "aws_security_group" "additional" { name_prefix = "${local.name}-additional" vpc_id = module.vpc.vpc_id ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = [ "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", ] } tags = merge(local.tags, { Name = "${local.name}-additional" }) } resource "aws_iam_policy" "additional" { name = "${local.name}-additional" policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = [ "ec2:Describe*", ] Effect = "Allow" Resource = "*" }, ] }) } module "kms" { source = "terraform-aws-modules/kms/aws" version = "1.1.0" aliases = ["eks/${local.name}"] description = "${local.name} cluster encryption key" enable_default_policy = true key_owners = [data.aws_caller_identity.current.arn] tags = local.tags }