From 1a057f77e416cfb18b5ebd46e8c01efbc82cc039 Mon Sep 17 00:00:00 2001 From: Anthony Zawacki Date: Wed, 16 Aug 2023 09:39:25 -0400 Subject: [PATCH] Initial commit. --- README.md | 65 +++++++++++++++++ istio_ports.tf | 84 ++++++++++++++++++++++ main.tf | 185 +++++++++++++++++++++++++++++++++++++++++++++++++ variables.tf | 76 ++++++++++++++++++++ version.tf | 4 ++ 5 files changed, 414 insertions(+) create mode 100644 README.md create mode 100644 istio_ports.tf create mode 100644 main.tf create mode 100644 variables.tf create mode 100644 version.tf diff --git a/README.md b/README.md new file mode 100644 index 0000000..c586038 --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +# tfmod-eks + +Create an EKS cluster given the specification of the cluster. + +## Required Inputs + +**cluster_name** `string` + +The name of the cluster to create. + + +**region** `string` + +The name of the region in which to create the cluster. + +## Optional Inputs + +**namespace** `string` + +The namespace to install the cloud watch components. + +Default: `"amazon-cloudwatch"` + + +**tags** `map(string)` + +Arbitrary tags to add to objects created in AWS. + +Default: `{}` + + +**log_retention_days** `string` + +How long to keep the logs in cloudwatch. + +Default: `"1"` + + +**fluent_bit_read_from_head** `string` + +Fluent Bit reads log files from the tail, and will capture only new logs after it is deployed. If you want the opposite, set fluent_bit_read_from_head='On' and it will collect all logs in the file system and set fluent_bit_read_from_tail='Off'. + +Default: `"off"` + + +**fluent_bit_read_from_tail** `string` + +Fluent Bit reads log files from the tail, and will capture only new logs after it is deployed. If you want the opposite, set fluent_bit_read_from_head='On' and it will collect all logs in the file system and set fluent_bit_read_from_tail='Off'. + +Default: `"on"` + + +**fluent_bit_http_server** `string` + +fluent_bit_http_server for monitoring plugin metrics is on by default. To turn it off, change this value to ''. + +Default: `"on"` + + +**fluent_bit_http_port** `string` + +The port on which the fluent_bit_http_server will run. + +Default: `"2020"` + diff --git a/istio_ports.tf b/istio_ports.tf new file mode 100644 index 0000000..13fd7d0 --- /dev/null +++ b/istio_ports.tf @@ -0,0 +1,84 @@ +locals { + istio_ports = [ + { + description = "Envoy admin port / outbound" + from_port = 15000 + to_port = 15001 + }, + { + description = "Debug port" + from_port = 15004 + to_port = 15004 + }, + { + description = "Envoy inbound" + from_port = 15006 + to_port = 15006 + }, + { + description = "HBONE mTLS tunnel port / secure networks XDS and CA services (Plaintext)" + from_port = 15008 + to_port = 15010 + }, + { + description = "XDS and CA services (TLS and mTLS)" + from_port = 15012 + to_port = 15012 + }, + { + description = "Control plane monitoring" + from_port = 15014 + to_port = 15014 + }, + { + description = "Control plane monitoring" + from_port = 15017 + to_port = 15017 + }, + { + description = "Merged Prometheus telemetry data from Istio agent, Envoy, and application, Health checks" + from_port = 15020 + to_port = 15021 + }, + { + description = "DNS port" + from_port = 15053 + to_port = 15053 + }, + { + description = "Envoy Prometheus telemetry" + from_port = 15090 + to_port = 15090 + }, + { + description = "aws-load-balancer-controller" + from_port = 9443 + to_port = 9443 + }, + ] + + ingress_rules = { + for ikey, ivalue in local.istio_ports : + "${ikey}_ingress" => { + description = ivalue.description + protocolo = "tcp" + from_port = ivalue.from_port + to_port = ivalue.to_port + type = "ingress" + self = true + } + } + + egress_rules = { + for ekey, evalue in local.istio_ports : + "${ekey}_egress" => { + description = evalue.description + protocol = "tcp" + from_port = evalue.from_port + to_port = evalue.to_port + type = "egress" + self = true + } + } + +} diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..5577e95 --- /dev/null +++ b/main.tf @@ -0,0 +1,185 @@ +data "aws_vpc" "eks_vpc" { + filter { + name = "tag:Name" + values = [var.vpc_name] + } +} + +data "aws_subnets" "subnets" { + filter { + name = "tag:Name" + values = [var.subnets_name] + } + filter { + name = "vpc-id" + values = [data.aws_vpc.eks_vpc.id] + } +} + +data "aws_subnet" "subnets" { + for_each = toset(data.aws_subnets.subnets.ids) + id = each.key +} + +data "aws_ebs_default_kms_key" "current" {} + +data "aws_kms_key" "ebs_key" { + key_id = data.aws_ebs_default_kms_key.current.key_arn +} + +locals { + vpc_id = data.aws_vpc.eks_vpc.id + vpc_cidr_block = data.aws_vpc.eks_vpc.cidr_block + subnets = [for k, v in data.aws_subnet.subnets : v.id if length(regexall("us-east-1e", v.availability_zone)) == 0] + + base_tags = { + "eks-cluster-name" = var.cluster_name + "boc:tf_module_version" = local._module_version + "boc:created_by" = "terraform" + } + + # https://docs.aws.amazon.com/eks/latest/userguide/cluster-autoscaler.html + autoscale_tags = { + format("k8s.io/cluster-autoscaler/%v", var.cluster_name) = "owned" + "k8s.io/cluster-autoscaler/enabled" = "TRUE" + } + + additional_policies = { + } + + ng_name = format("%v-ng-on_demand", var.cluster_name) + ng_asg_name = module.cluster.eks_managed_node_groups["on_demand"].node_group_resources[0].autoscaling_groups[0].name + + tags = merge( + local.base_tags, + local.common_tags, + var.tags, + var.application_tags + ) +} + +module "vpc_cni_irsa_role" { + source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + + role_name = "${var.cluster_name}-vpc-cni" + + attach_vpc_cni_policy = true + vpc_cni_enable_ipv4 = true + + oidc_providers = { + main = { + provider_arn = module.cluster.oidc_provider_arn + namespace_service_accounts = ["kube-system:aws-node"] + } + } + tags = local.tags +} + +module "ebs_csi_irsa_role" { + source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + + role_name = "${var.cluster_name}-ebs-csi-driver" + attach_ebs_csi_policy = true + + oidc_providers = { + main = { + provider_arn = module.cluster.oidc_provider_arn + namespace_service_accounts = ["kube-system:ebs-csi-controller-sa"] + } + } + tags = local.tags +} + +module "cluster" { + source = "terraform-aws-modules/eks/aws" + version = "19.16.0" + + cluster_name = var.cluster_name + cluster_version = var.cluster_version + + cluster_enabled_log_types = [ + "audit", + "api", + "authenticator", + "controllerManager", + "scheduler", + ] + + vpc_id = local.vpc_id + subnet_ids = local.subnets + + cluster_addons = { + coredns = { + most_recent = false + } + kube-proxy = { + most_recent = false + } + vpc-cni = { + most_recent = false + service_account_role_arn = module.vpc_cni_irsa_role.iam_role_arn + } + aws-ebs-csi-driver = { + most_recent = false + service_account_role_arn = module.ebs_csi_irsa_role.iam_role_arn + } + } + + eks_managed_node_group_defaults = { + ami_type = "AL2_x86_64" + } + + node_security_group_additional_rules = merge( + local.ingress_rules, + local.egress_rules, + ) + + eks_managed_node_groups = { + name = local.ng_name + capacity_type = "ON_DEMAND" + + instance_types = var.eks_instance_types + + min_size = var.eks_ng_min_size + max_size = var.eks_ng_max_size + desired_size = var.eks_ng_desired_size + + iam_role_additional_policies = local.additional_policies + + block_device_mappings = { + xvda = { + device_name = "/dev/xvda" + ebs = { + volume_size = var.eks_instance_disk_size + volume_type = "gp3" + iops = 3000 + throughput = 125 + encrypted = true + delete_on_termination = true + } + } + } + } + + tags = local.tags +} + +resource "aws_security_group_rule" "allow_sidecar_injection" { + description = "Webhook container port, from Control Plane" + protocol = "tcp" + type = "ingress" + from_port = 15017 + to_port = 15017 + + security_group_id = module.cluster.node_security_group_id + source_security_group_id = module.cluster.cluster_primary_security_group_id +} + +resource "aws_autoscaling_group_tag" "on-demand" { + autoscaling_group_name = local.ng_asg_name + tag { + key = "k8s.io/cluster-autoscaler/node-template/label/eks.amazonaws.com/capacityType" + value = "ON_DEMAND" + propagate_at_launch = true + } +} diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..3142d67 --- /dev/null +++ b/variables.tf @@ -0,0 +1,76 @@ +variable "tag_costallocation" { + description = "Tag CostAllocation (default)" + type = string + default = "csvd:infrastructure" +} + +variable "region" { + description = "AWS region" + type = string +} + +variable "profile" { + description = "AWS config profile" + type = string + default = "" +} + +variable "vpc_name" { + description = "Define the VPC name that will be used by this cluster" + type = string + default = "*UNKNOWN*" +} + +variable "subnets_name" { + description = "Define the name of the subnets to be used by this cluster" + type = string + default = "*-container-*" +} + +variable "cluster_name" { + description = "EKS cluster name name component used through out the EKS cluster describing its purpose (ex: dice-dev)" + type = string + default = null +} + +variable "cluster_version" { + description = "The EKS version number, see https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html" + type = string + default = "1.27" +} + +variable "domain" { + description = "The DNS domain name of the cluster. Defaults to empty which causes the sample application to use the domain assigned to the load balancer of the istio ingress gateway." + type = string + default = "" +} + +variable "eks_instance_disk_size" { + description = "The size of the disk in gigabytes" + type = number + default = 40 +} + +variable "eks_instance_types" { + description = "EKS worker node instance type" + type = list(string) + default = [ + "t3.xlarge" + ] +} + +variable "eks_ng_desired_size" { + description = "Node Group desire size, default is 1" + type = number + default = 4 +} +variable "eks_ng_max_size" { + description = "Node Group minimum size, default is 1" + type = number + default = 4 +} +variable "eks_ng_min_size" { + description = "Node Group maximum size, default is 10" + type = number + default = 16 +} diff --git a/version.tf b/version.tf new file mode 100644 index 0000000..b48cf73 --- /dev/null +++ b/version.tf @@ -0,0 +1,4 @@ +locals { + _module_name = "tfmod-eks" + _module_version = "unknown" +}