diff --git a/README.md b/README.md index 3f23550..f29708f 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,113 @@ # tfmod-eks-configuration -The module configures an eks cluster with additional components after the cluster is created. - -- Storage classes - - A gp3-encrypted storage class is created and made the default storage class - - This storage class is returned as the `rwo_storage_class` - - A gp2-encrypted storage class is created - - An efs storage class is created - - This storage class is returned as the `rwx_storage_class` - -A successful apply will yield: -Apply complete! Resources: 14 added, 0 changed, 0 destroyed. -Outputs: -module_name = "tfmod-eks-configuration" -module_version = "0.1.1" -rwo_storage_class = "gp3-encrypted" -rwx_storage_class = "efs" -real 2m4.048s -user 0m23.112s -sys 0m3.855s - -A successful destroy will yield: -Destroy complete! Resources: 14 destroyed. -real 0m43.539s -user 0m17.060s -sys 0m2.015s +This module configures an EKS cluster with essential components and best practices after cluster creation. + +## Features + +### Storage Classes +- **GP3 Encrypted (Default)** + - Support for ReadWriteOnce (RWO) + - Volume binding mode: WaitForFirstConsumer + - Automatic encryption using AWS KMS + - Configured as cluster default + +- **GP2 Encrypted (Legacy)** + - Support for ReadWriteOnce (RWO) + - Volume binding mode: Immediate + - Maintained for backwards compatibility + +- **EFS (Shared Storage)** + - Support for ReadWriteMany (RWX) + - Automatic encryption + - Lifecycle policy: transition to IA after 30 days + - Perfect for shared storage needs + +### Namespace Management +- Dedicated `operators` namespace for cluster operators +- Secure default network policies +- Standardized labels for resource tracking + +### Security +- Default network policies for operator namespace +- Encrypted storage by default +- TLS-enabled EFS mounts +- Restricted egress policies + +### AWS Console Access +- Full and restricted access roles +- Helm-managed deployments +- Standard RBAC configurations + +## Usage + +Basic usage to configure cluster storage and operators: + +```hcl +module "eks_configuration" { + source = "git@github.e.it.census.gov:SOA/tfmod-eks-configuration.git//" + + cluster_name = "my-cluster" + vpc_id = "vpc-1234567890abcdef0" + subnets = ["subnet-1234567890abcdef0", "subnet-0fedcba0987654321"] + + security_group_all_worker_mgmt_id = "sg-1234567890abcdef0" + release_version = "1.0.0" + + tags = { + Environment = "production" + Project = "platform" + } +} +``` + +### Verifying the Installation + +1. Check storage classes: +```bash +$ kubectl get storageclasses +NAME PROVISIONER AGE +gp3-encrypted (default) ebs.csi.aws.com 10m +gp2-encrypted kubernetes.io/aws-ebs 10m +efs efs.csi.aws.com 10m +``` + +2. Verify operator namespace: +```bash +$ kubectl get namespace operators --show-labels +NAME STATUS AGE LABELS +operators Active 10m app.kubernetes.io/managed-by=terraform,app.kubernetes.io/part-of=my-cluster +``` + +3. Test EFS storage: +```bash +$ kubectl -n operators create -f - < ## Requirements diff --git a/cluster_autoscaler.tf.off b/cluster_autoscaler.tf.off deleted file mode 100644 index ef30dc9..0000000 --- a/cluster_autoscaler.tf.off +++ /dev/null @@ -1,102 +0,0 @@ -locals { - # 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" - } - - ng_asg_name = var.eks_managed_node_groups_autoscaling_group_names[0] -} - -# module "cluster_autoscaler_irsa_role" { -# source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" - -# role_name = "${var.cluster_name}-cluster-autoscaler" - -# attach_cluster_autoscaler_policy = true - -# cluster_autoscaler_cluster_names = [var.cluster_name] - -# oidc_providers = { -# main = { -# provider_arn = var.oidc_provider_arn -# namespace_service_accounts = ["kube-system:cluster-autoscaler"] -# } -# } -# tags = local.tags -# } - -# ALTERNATELY WE PASS THIS VIA OUTPUT DEPENDENCY W/ TERRAGRUNT -data "aws_iam_role" "cluster_autoscaler_irsa_role" { - name = "${var.cluster_name}-cluster-autoscaler" -} - -#### NEED TO MOVE THIS TO A PROPER PLACE -resource "kubernetes_namespace" "operators" { - metadata { - name = var.operators_ns - } -} - -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 - } -} - -data "kubernetes_namespace" "kube-system" { - metadata { - name = "kube-system" - } -} - -resource "helm_release" "cluster-autoscaler" { - depends_on = [ - module.images, - ] - - chart = "cluster-autoscaler" - name = "cluster-autoscaler" - version = var.cluster_autoscaler_chart_version - namespace = data.kubernetes_namespace.kube-system.metadata[0].name - repository = "https://kubernetes.github.io/autoscaler" - - set { - name = "image.repository" - value = format("%v/%v", - module.images.images[local.autoscaler_key].dest_registry, - module.images.images[local.autoscaler_key].dest_repository - ) - } - set { - name = "image.tag" - value = module.images.images[local.autoscaler_key].tag - } - set { - name = "autoDiscovery.clusterName" - value = var.cluster_name - } - set { - name = "awsRegion" - value = var.region - } - - set { - name = "rbac.serviceAccount.name" - value = "cluster-autoscaler" - } - - set { - name = "rbac.serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn" - value = data.aws_iam_role.cluster_autoscaler_irsa_role.arn - # value = module.cluster_autoscaler_irsa_role.iam_role_arn - } - - set { - name = "rbac.serviceAccount.create" - value = "true" - } -} diff --git a/copy_images.tf.off b/copy_images.tf.off deleted file mode 100644 index dccba9e..0000000 --- a/copy_images.tf.off +++ /dev/null @@ -1,29 +0,0 @@ -locals { - kubectl_key = format("%v#%v", "kubectl", var.kubectl_image_tag) - - image_config = [ - { - enabled = true - dest_path = null - name = "kubectl" - source_image = "bitnami/kubectl" - source_registry = "docker.io" - source_tag = var.kubectl_image_tag - tag = var.kubectl_image_tag - } - ] -} - -module "images" { - source = "git@github.e.it.census.gov:terraform-modules/aws-ecr-copy-images.git/?ref=tf-upgrade" - - profile = var.profile - application_name = var.cluster_name - image_config = local.image_config - tags = {} - - enable_lifecycle_policy = true - lifecycle_policy_all = true - force_delete = true - lifecycle_policy_keep_count = 3 -} diff --git a/efs-filesystem.tf.off b/efs-filesystem.tf.off deleted file mode 100644 index 667f8cd..0000000 --- a/efs-filesystem.tf.off +++ /dev/null @@ -1,149 +0,0 @@ -# ------------------------------------------------------------------------------------- -# EKS-EFS - Creates an EFS volume and Kubernetes resources to use it -# ------------------------------------------------------------------------------------- -locals { - efs_access_points = [ - { - label = "data-logs" - name = "data-logs" - path = "/data_logs" - owner_uid = 51000 - owner_gid = 51000 - permissions = "755" - claim_name = "logs" - claim_namespace = "logs" - }, - { - label = "data-apps" - name = "data-apps" - path = "/data_apps" - owner_uid = 51000 - owner_gid = 51000 - permissions = "755" - claim_name = "apps" - claim_namespace = "apps" - }, - ] -} - -# ------------------------------------------------------------------------------------- -# EFS Namespace -# ------------------------------------------------------------------------------------- -resource "kubernetes_namespace" "efs_namespace" { - for_each = { for ap in local.efs_access_points : ap.label => ap } - metadata { - name = format("%v-%v", var.cluster_name, each.value.claim_namespace) - } -} - -# ------------------------------------------------------------------------------------- -# EFS Access Point -# ------------------------------------------------------------------------------------- -resource "aws_efs_access_point" "efs_ap" { - for_each = { for ap in local.efs_access_points : ap.name => ap } - file_system_id = module.efs.id - root_directory { - path = each.value.path - creation_info { - owner_uid = each.value.owner_uid - owner_gid = each.value.owner_gid - permissions = each.value.permissions - } - } - - tags = merge( - local.base_tags, - # local.common_tags, - # var.application_tags, - tomap({ "Name" = format("%v-efs-access-point_%v", var.cluster_name, each.key) }), - ) -} - -# ------------------------------------------------------------------------------------- -# EFS Persistent Volume -# ------------------------------------------------------------------------------------- -resource "kubernetes_persistent_volume" "efs_ap" { - for_each = { for ap in local.efs_access_points : ap.name => ap } - metadata { - name = format("efs-%v-pv", each.key) - } - spec { - capacity = { - storage = "1Gi" - } - claim_ref { - name = format("%v-%v-%v-claim", var.cluster_name, each.value.claim_namespace, each.key) - namespace = format("%v-%v", var.cluster_name, each.value.claim_namespace) - } - access_modes = ["ReadWriteMany"] - persistent_volume_reclaim_policy = "Retain" - volume_mode = "Filesystem" - storage_class_name = "efs" - persistent_volume_source { - csi { - driver = "efs.csi.aws.com" - volume_handle = format("%v:%v:%v", module.efs.id, "", aws_efs_access_point.efs_ap[each.key].id) - } - } - } -} -# ------------------------------------------------------------------------------------- -# EFS Persistent Volume Claim Per AP -# ------------------------------------------------------------------------------------- -resource "kubernetes_persistent_volume_claim" "efs_ap" { - for_each = { for ap in local.efs_access_points : ap.name => ap } - metadata { - name = format("%v-%v-%v-claim", var.cluster_name, each.value.claim_namespace, each.key) - namespace = format("%v-%v", var.cluster_name, each.value.claim_namespace) - } - wait_until_bound = false - spec { - access_modes = ["ReadWriteMany"] - storage_class_name = "efs" - resources { - requests = { - storage = "1Gi" - } - } - } - depends_on = [kubernetes_persistent_volume.efs_ap] -} - -# ------------------------------------------------------------------------------------- -# EFS Persistent Volume Base Claim -# ------------------------------------------------------------------------------------- -resource "kubernetes_persistent_volume_claim" "pvc_efs-cluster-base" { - depends_on = [kubernetes_storage_class.efs-sc] - metadata { - name = format("%v%v-%v", "eks-", var.cluster_name, "base-claim") - } - wait_until_bound = false - spec { - access_modes = ["ReadWriteMany"] - resources { - requests = { - storage = "25Gi" - } - } - storage_class_name = "efs" - } -} - -output "efs_ap_ids" { - description = "EFS AccessPoint IDs" - value = { for k, v in aws_efs_access_point.efs_ap : k => v.id } -} - -## # apiVersion: v1 -## # kind: PersistentVolumeClaim -## # metadata: -## # name: ditd-gups-dev1-data1-geoserver-claim -## # spec: -## # accessModes: -## # - ReadWriteMany -## # storageClassName: efs-sc -## # resources: -## # requests: -## # storage: 5Gi -## # -##