diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..bb69bc5 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,2 @@ +# These owners will be the default owners for everything in the repo. Unless a later match takes precedence +* @SCT-Engineering/terraform-reviewers diff --git a/README.md b/README.md index b3ebedc..0f4dd26 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,39 @@ -# csvd-mcm2-lab -EKS Cluster Configuration for csvd-mcm2-lab +# EKS Cluster Configuration - CSVD-MCM2-LAB - LAB + +This EKS cluster configuration was generated using Terraform and the terraform-eks-deployment module. + +## Environment Details + +- **Environment**: lab +- **Region**: us-gov-east-1 +- **Cluster Name**: csvd-mcm2-lab + +## Directory Structure + +## Getting Started + +To apply this configuration: + +1. Change to the directory of the module you want to deploy: + ``` + cd environment/region/vpc/cluster/eks + ``` + +2. Initialize and apply the Terragrunt configuration: + ``` + terragrunt init + terragrunt plan + terragrunt apply + ``` + +3. Deploy additional modules as needed: + ``` + cd ../eks-cconfig + terragrunt init + terragrunt plan + terragrunt apply + ``` + +## Customization + +Each module can be deployed independently using Terragrunt. \ No newline at end of file diff --git a/_envcommon/common-variables.hcl b/_envcommon/common-variables.hcl new file mode 100644 index 0000000..1260c08 --- /dev/null +++ b/_envcommon/common-variables.hcl @@ -0,0 +1,82 @@ +# lab/_envcommon/common-variables.hcl + +# --------------------------------------------------------------------------------------------------------------------- +# GLOBAL PARAMETERS +# These are the variables we pass to use across modules regardless of environment, i.e. these are the parameters +# that are common across all environments/accounts. +# --------------------------------------------------------------------------------------------------------------------- +locals { + state_bucket_prefix = "inf-tfstate" + state_table_name = "tf_remote_state" + environment_abbr = "lab" + + route53_endpoints = { + route53_main = { + "account_id" = local.route53_info[local.environment_abbr]["account_id"] + "alias" = local.route53_info[local.environment_abbr]["alias"] + "us-gov-east-1" = local.route53_info[local.environment_abbr]["us-gov-east-1"] + "us-gov-west-1" = local.route53_info[local.environment_abbr]["us-gov-west-1"] + } + route53_main_legacy = { + "account_id" = local.route53_info["legacy"]["account_id"] + "alias" = local.route53_info["legacy"]["alias"] + "us-gov-east-1" = local.route53_info["legacy"]["us-gov-east-1"] + "us-gov-west-1" = local.route53_info["legacy"]["us-gov-west-1"] + } + } + + route53_info = { + lab = { + "account_id" = "269244441389" + "alias" = "lab-gov-network-nonprod" + "us-gov-east-1" = "vpc-070595c5b133243dd" + "us-gov-west-1" = "vpc-08b7b4db6a5ddf9c1" + } + dev = { + "account_id" = "057405694017" + "alias" = "ent-ew-network-prod" + "us-gov-east-1" = "vpc-061325b37d748d17a" + "us-gov-west-1" = "vpc-0b22b68b90e47cb5f" + } + prod = { + "account_id" = "057405694017" + "alias" = "ent-ew-network-prod" + "us-gov-east-1" = "vpc-061325b37d748d17a" + "us-gov-west-1" = "vpc-0b22b68b90e47cb5f" + } + legacy = { + "account_id" = "107742151971" + "alias" = "do2-govcloud" + "us-gov-east-1" = "vpc-099a991da7c4eb8a5" + "us-gov-west-1" = "vpc-77877a12" + } + } + + enterprise_ecr_account = { + lab = { + "account_id" = "269222635945" + "alias" = "lab-gov-shared-nonprod" + "profile" = "269222635945-lab-gov-shared-nonprod" + "region" = "us-gov-east-1" + } + dev = { + "account_id" = "067074201825" + "alias" = "ent-gov-shared-prod" + "profile" = "067074201825-ent-gov-shared-prod" + "region" = "us-gov-east-1" + } + prod = { + "account_id" = "067074201825" + "alias" = "ent-gov-shared-prod" + "profile" = "067074201825-ent-gov-shared-prod" + "region" = "us-gov-east-1" + } + } + + eecr_info = { + account_id = local.enterprise_ecr_account[local.environment_abbr]["account_id"] + alias = local.enterprise_ecr_account[local.environment_abbr]["alias"] + profile = local.enterprise_ecr_account[local.environment_abbr]["profile"] + region = local.enterprise_ecr_account[local.environment_abbr]["region"] + } +} \ No newline at end of file diff --git a/_envcommon/default-versions.hcl b/_envcommon/default-versions.hcl new file mode 100644 index 0000000..c4e815f --- /dev/null +++ b/_envcommon/default-versions.hcl @@ -0,0 +1,225 @@ +# lab/_envcommon/default-versions.hcl +locals { + module_name = basename(get_original_terragrunt_dir()) + release_version = local.module_versions["2026.03.15"][local.module_name] + + ##################### + # Module Versions + ##################### + cluster_version = "1.34" + eks_module_version = "21.11.1" + + module_versions = { + "2025.20.04" = { + "eks-arcgis" = false + "eks-cert-manager" = "0.1.9" + "eks-config" = "1.0.5" + "eks-cribl" = "0.0.1" + "eks-dns" = "0.1.4" + "eks-gatekeeper" = "0.0.3" + "eks-grafana" = "0.1.5" + "eks-istio" = "1.0.9" + "eks-k8s-dashboard" = "0.1.4" + "eks-karpenter" = "0.1.7" + "eks-keycloak" = "0.0.8" + "eks-kiali" = "0.1.4" + "eks-loki" = "0.1.4" + "eks-metrics-server" = "0.1.4" + "eks-otel" = "0.0.4" + "eks-pipeline" = "initial" + "eks-postgresql" = false + "eks-prometheus" = "0.1.4" + "eks-tempo" = "0.1.4" + "eks" = "1.0.10" + "cluster" = "2025.20.04" + } + "2026.03.15" = { + "eks-arcgis" = false + "eks-config" = "1.0.6" + "eks-cribl" = "mcm_v2" + "eks-dns" = "0.1.7" + "eks-gatekeeper" = "0.0.4" + "eks-grafana" = "0.1.5" + "eks-istio" = "1.0.9" + "eks-karpenter" = "0.1.9" + "eks-keycloak" = "0.0.8" + "eks-kiali" = "0.1.5" + "eks-loki" = "0.1.6" + "eks-otel" = "0.0.4" + "eks-pipeline" = "initial" + "eks-postgresql" = false + "eks-prometheus" = "0.1.5" + "eks-tempo" = "0.1.6" + "eks" = "1.0.14" + "cluster" = "2026.03.15" + } + } + + submodule_versions = { + "tfmod-istio-service-ingress" = "0.1.7" + "tfmod-config-job" = "0.1.8" + "tfmod-custom-iam-role-for-service-account-eks" = "1.0.1" + } + + ##################### + # Module Enablement + ##################### + + # Core modules that should always be enabled (cannot be disabled) + core_modules = [ + "eks", + "eks-karpenter", + "eks-config", + "eks-istio", + "eks-dns", + ] + + # Optional modules with their default enablement state + enabled_modules = { + "eks-arcgis" = false + "eks-cribl" = false + "eks-gatekeeper" = true + "eks-grafana" = true + "eks-keycloak" = true + "eks-kiali" = true + "eks-loki" = true + "eks-otel" = true + "eks-pipeline" = false + "eks-postgresql" = false + "eks-prometheus" = true + "eks-tempo" = true + } + + ##################### + # TF Providers + ##################### + aws_version = "6.0" + helm_version = "2.11.0" + kubernetes_version = "2.33.0" + null_version = "3.2.1" + random_version = "3.5.1" + template_version = "2.2.0" + tf_version = "1.5.5" + + ##################### + # Namespaces Config + ##################### + operator_namespace = "operator" + telemetry_namespace = "telemetry" + system_namespace = "kube-system" + istio_namespace = "istio-system" + namespaces = { + arcgis = "arcgis" + cribl = "cribl" + gatekeeper = "keycloak" + grafana = local.telemetry_namespace + istio = local.istio_namespace + karpenter = local.system_namespace + keycloak = "keycloak" + kiali = local.istio_namespace + loki = local.telemetry_namespace + misp = "misp" + otel = local.telemetry_namespace + postgresql = "keycloak" + prometheus = local.telemetry_namespace + tempo = local.telemetry_namespace + } + + ##################### + # EKS Config + ##################### + + ################ + # Cert-Manager + ################ + cluster_issuer_name = "cert-manager" + + ##################### + # Cribl + ##################### + cribl_chart_version = "4.15.1" + cribl_app_version = "4.15.1" + + ################ + # GoGatekeeper + ################ + gatekeeper_tag = "4.4.0" + gatekeeper_chart_version = "0.1.60" + gatekeeper_service_name = "gatekeeper" + + ################ + # Grafana + ################ + grafana_hostname = "grafana" + grafana_operator_chart_version = "4.9.8" + grafana_operator_tag = "5.16.0" + grafana_tag = "11.5.2" + os_shell_image_tag = local.utilities_tag + + ################ + # Istio + ################ + istio_version = "1.28.3" + + ################ + # Karpenter + ################ + karpenter_helm_chart = "1.8.5" + karpenter_tag = "1.8.5" + + ################ + # Keycloak + ################ + keycloak_chart_version = "7.0.1" + keycloak_tag = "26.0.7" + postgresql_tag = "17.4.0-debian-12-r4" + postgres_exporter_tag = "0.17.1-debian-12-r0" + utilities_tag = "1.0.3" + + ################ + # Kiali + ################ + kiali_operator_version = "2.21.0" + kiali_application_version = "${local.kiali_operator_version}" + + ################ + # Loki + ################ + loki_chart_version = "6.49.0" + loki_tag = "3.6.3" + enterprise_logs_provisioner_tag = "3.6.2" + gateway_tag = "1.29.4" + memcached_tag = "1.6.40" + exporter_tag = "v0.15.3" + sidecar_tag = "2.4.0" + + ################ + # Open Telemetry + ################ + auto_instrumentation_java_version = "2.9.0" + collector_contrib_version = "0.113.0-amd64" + collector_version = "0.111.0-amd64" + otel_helm_version = "0.71.2" + otel_version = "0.110.0" + rbac_proxy_version = "0.20.2" + + ################ + # PostgreSQL + ################ + postgresql_chart_version = "16.5.0" + + ################ + # Prometheus + ################ + prometheus_chart_version = "28.6.0" + prometheus_server_tag = "v3.9.1" + prometheus_config_reloader_tag = "v0.88.0" + alertmanager_tag = "v0.30.1" + pushgateway_tag = "v1.6.2" + + ################ + # Tempo + ################ + tempo_chart_version = "1.24.3" + tempo_tag = "2.9.1" +} \ No newline at end of file diff --git a/_envcommon/prefixes.hcl b/_envcommon/prefixes.hcl new file mode 100644 index 0000000..d46f6bb --- /dev/null +++ b/_envcommon/prefixes.hcl @@ -0,0 +1,37 @@ +locals { + prefixes = { + "ebs" = "v-ebs-" + "efs" = "v-efs-" + "group" = "g-" + "kms" = "k-kms-" + "policy" = "p-" + "role" = "r-" + "s3" = "v-s3-" + "security-group" = "" # "sg-" + # VPC + "customer-gateway" = "cgw-" + "dhcp-options" = "" + "elastic-ip" = "eip-" + "internet-gateway" = "igw-" + "log-group" = "lg-" + "log-stream" = "lgs-" + "nat-gateway" = "nat-" + "network-acl" = "nacl-" + "route-table" = "route-" + "subnet" = "" + "vpc-endpoint" = "vpce-" + "vpc-peer" = "vpcp-" + "vpc" = "" + "vpn-connection" = "vpn_" + "vpn-gateway" = "vpcg-" + # EKS + "eks-policy" = "p-eks-" + "eks-queue" = "eks-q-" + "eks-role" = "r-eks-" + "eks-s3" = "v-s3-eks-" + "eks-security-group" = "eks-sg-" # "sg-eks-" + "eks-user" = "s-eks-" + "eks" = "eks-" + "eks-event" = "eks-ev-" + } +} diff --git a/config.json b/config.json new file mode 100644 index 0000000..8bcb61c --- /dev/null +++ b/config.json @@ -0,0 +1 @@ +{"account":{"account_name":"lab-dev-gov","aws_account_id":"224384469011","aws_profile":"lab-dev-gov-lab","environment_abbr":"lab"},"cluster":{"CostAllocation":"census:ocio:csvd","cluster_mailing_list":"matthew.c.morgan@census.gov","cluster_name":"csvd-mcm2-lab","eks_instance_disk_size":200,"eks_ng_desired_size":2,"eks_ng_max_size":10,"eks_ng_min_size":2,"finops_project_name":"csvd_platformbaseline","finops_project_number":"fs0000000078","finops_project_role":"csvd_platformbaseline_eks","organization":"census:ocio:csvd","tags":{"CostAllocation":"census:ocio:csvd","Owner":"matthew.c.morgan@census.gov","PowerSchedule":"Full_Week_Core_Hours_7-7"}},"cluster_dir":"csvd-mcm2-lab","enable_all_modules":true,"environment":"lab","modules":{"cribl":false,"gatekeeper":false,"grafana":false,"keycloak":false,"kiali":false,"loki":false,"otel":false,"prometheus":false,"tempo":false},"region":"us-gov-east-1","vpc":{"vpc_domain_name":"dev.lab.csp2.census.gov","vpc_name":"vpc3-lab-dev"}} \ No newline at end of file diff --git a/lab/account.hcl b/lab/account.hcl new file mode 100644 index 0000000..c246c8a --- /dev/null +++ b/lab/account.hcl @@ -0,0 +1,10 @@ +# lab/environment.hcl + +# Set account-wide variables. These are automatically pulled in to configure the remote state bucket in the root +# terragrunt.hcl configuration. +locals { + account_name = "lab-dev-gov" + aws_account_id = "224384469011" + aws_profile = format("%v-%v", local.aws_account_id, replace(local.account_name, "-ew", "-gov")) + environment = "lab" +} diff --git a/lab/us-gov-east-1/region.hcl b/lab/us-gov-east-1/region.hcl new file mode 100644 index 0000000..edc631f --- /dev/null +++ b/lab/us-gov-east-1/region.hcl @@ -0,0 +1,7 @@ +# lab/us-gov-east-1/region.hcl + +# Set common variables for the region. This is automatically pulled in in the root terragrunt.hcl configuration to +# configure the remote state bucket and pass forward to the child modules as inputs. +locals { + aws_region = "us-gov-east-1" +} diff --git a/lab/us-gov-east-1/vpc/cluster/cluster.hcl b/lab/us-gov-east-1/vpc/cluster/cluster.hcl new file mode 100644 index 0000000..3447af6 --- /dev/null +++ b/lab/us-gov-east-1/vpc/cluster/cluster.hcl @@ -0,0 +1,16 @@ +locals { + # Cluster specific configuration + cluster_name = "csvd-mcm2-lab" + cluster_mailing_list = "matthew.c.morgan@census.gov" + eks_instance_disk_size = 200 + eks_ng_desired_size = 2 + eks_ng_max_size = 10 + eks_ng_min_size = 2 + organization = "census:ocio:csvd" + CostAllocation = "census:ocio:csvd" + finops_project_name = "csvd_platformbaseline" + finops_project_number = "fs0000000078" + finops_project_role = "csvd_platformbaseline_eks" + tags = {"CostAllocation":"census:ocio:csvd","Owner":"matthew.c.morgan@census.gov","PowerSchedule":"Full_Week_Core_Hours_7-7"} + module_enablement_overrides = {"cribl":false,"gatekeeper":false,"grafana":false,"keycloak":false,"kiali":false,"loki":false,"otel":false,"prometheus":false,"tempo":false} +} diff --git a/lab/us-gov-east-1/vpc/cluster/eks-config/terragrunt.hcl b/lab/us-gov-east-1/vpc/cluster/eks-config/terragrunt.hcl new file mode 100644 index 0000000..5297ebb --- /dev/null +++ b/lab/us-gov-east-1/vpc/cluster/eks-config/terragrunt.hcl @@ -0,0 +1,65 @@ +include "root" { + path = find_in_parent_folders("root.hcl") + merge_strategy = "deep" + expose = true +} + +locals { + # Skip this module if disabled + skip = !lookup(include.root.locals.is_module_enabled, basename(get_terragrunt_dir()), true) +} + +exclude { + if = local.skip + actions = ["all_except_output"] + exclude_dependencies = false +} + +terraform { + source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-eks-configuration.git?ref=${include.root.inputs.release_version}" + + extra_arguments "retry_lock" { + commands = get_terraform_commands_that_need_locking() + arguments = ["-lock-timeout=20s"] + } +} + +dependency "eks" { + config_path = "../eks" + mock_outputs_allowed_terraform_commands = ["init", "plan", "validate", "destroy"] + + mock_outputs = { + cluster_name = "mock-cluster" + cluster_endpoint = "https://mock-endpoint.eks.amazonaws.com" + cluster_certificate_authority_data = [{ data = "mock-cert-data" }] + eks_managed_node_groups_autoscaling_group_names = ["mock-asg-name"] + oidc_provider_arn = "arn:aws-us-gov:iam::123456789012:oidc-provider/mock" + security_group_all_worker_mgmt_id = "sg-mock" + subnets = ["subnet-mock1", "subnet-mock2"] + vpc_id = "vpc-mock" + } +} + +dependencies { + paths = [ + "../eks", + "../eks-karpenter", + ] +} + +inputs = { + # AWS Configuration + account_id = include.root.inputs.aws_account_id + profile = include.root.inputs.aws_profile + region = include.root.inputs.aws_region + + # Core Cluster Configuration + cluster_name = dependency.eks.outputs.cluster_name + eks_managed_node_groups_autoscaling_group_names = dependency.eks.outputs.eks_managed_node_groups_autoscaling_group_names + oidc_provider_arn = dependency.eks.outputs.oidc_provider_arn + security_group_all_worker_mgmt_id = dependency.eks.outputs.security_group_all_worker_mgmt_id + subnets = dependency.eks.outputs.subnets + vpc_id = dependency.eks.outputs.vpc_id + operators_ns = include.root.inputs.operator_namespace + telemetry_ns = include.root.inputs.telemetry_namespace +} diff --git a/lab/us-gov-east-1/vpc/cluster/eks-dns/terragrunt.hcl b/lab/us-gov-east-1/vpc/cluster/eks-dns/terragrunt.hcl new file mode 100644 index 0000000..983ab4f --- /dev/null +++ b/lab/us-gov-east-1/vpc/cluster/eks-dns/terragrunt.hcl @@ -0,0 +1,71 @@ +include "root" { + path = find_in_parent_folders("root.hcl") + merge_strategy = "deep" + expose = true +} + +locals { + # Skip this module if disabled + skip = !lookup(include.root.locals.is_module_enabled, basename(get_terragrunt_dir()), true) +} + +exclude { + if = local.skip + actions = ["all_except_output"] + exclude_dependencies = false +} + +terraform { + source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-eks-dns.git?ref=${include.root.inputs.release_version}" + extra_arguments "retry_lock" { + commands = get_terraform_commands_that_need_locking() + arguments = ["-lock-timeout=20s"] + } +} + +dependency "eks" { + config_path = "../eks" + mock_outputs_allowed_terraform_commands = ["init", "plan", "validate", "destroy"] + mock_outputs = { + cluster_name = include.root.inputs.cluster_name + subnets = ["subnet-mock1", "subnet-mock2", "subnet-mock3"] + } +} + +dependency "eks-istio" { + config_path = "../eks-istio" + mock_outputs_allowed_terraform_commands = ["init", "plan", "validate", "destroy"] + mock_outputs = { + istio_ingress_lb = { + dns_name = "mock-${include.root.inputs.cluster_name}.elb.amazonaws.com" + zone_id = "MOCKZONEID" + } + } +} + +dependencies { + paths = [ + "../eks", + "../eks-istio", + ] +} + +inputs = { + # AWS Configuration + account_id = include.root.inputs.aws_account_id + profile = include.root.inputs.aws_profile + region = include.root.inputs.aws_region + + # Cluster Configuration + cluster_name = include.root.inputs.cluster_name + environment_abbr = include.root.inputs.environment_abbr + + # Network Configuration + istio_ingress_lb = dependency.eks-istio.outputs.istio_ingress_lb + route53_endpoints = include.root.inputs.route53_endpoints + vpc_domain_name = include.root.inputs.vpc_domain_name + vpc_name = include.root.inputs.vpc_name + + # Additional Configuration + tags = include.root.inputs.tags +} diff --git a/lab/us-gov-east-1/vpc/cluster/eks-istio/terragrunt.hcl b/lab/us-gov-east-1/vpc/cluster/eks-istio/terragrunt.hcl new file mode 100644 index 0000000..fadb1ae --- /dev/null +++ b/lab/us-gov-east-1/vpc/cluster/eks-istio/terragrunt.hcl @@ -0,0 +1,54 @@ +include "root" { + path = find_in_parent_folders("root.hcl") + merge_strategy = "deep" + expose = true +} + +locals { + # Skip this module if disabled + skip = !lookup(include.root.locals.is_module_enabled, basename(get_terragrunt_dir()), true) +} + +exclude { + if = local.skip + actions = ["all_except_output"] + exclude_dependencies = false +} + +terraform { + source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-istio.git?ref=${include.root.inputs.release_version}" + extra_arguments "retry_lock" { + commands = get_terraform_commands_that_need_locking() + arguments = ["-lock-timeout=20s"] + } +} + +dependencies { + paths = [ + "../eks" + ] +} + +dependency "eks" { + config_path = "../eks" + mock_outputs_allowed_terraform_commands = ["init", "plan", "validate", "destroy"] + mock_outputs = { + cluster_name = include.root.inputs.cluster_name + } +} + +inputs = { + # AWS Configuration + account_id = include.root.inputs.aws_account_id + eecr_info = include.root.inputs.eecr_info + profile = include.root.inputs.aws_profile + region = include.root.inputs.aws_region + + # Cluster Configuration + cluster_name = dependency.eks.outputs.cluster_name + + # Istio Configuration + namespace = include.root.inputs.namespaces["istio"] + istio_version = include.root.inputs.istio_version + istio_chart_version = include.root.inputs.istio_version +} diff --git a/lab/us-gov-east-1/vpc/cluster/eks-karpenter/terragrunt.hcl b/lab/us-gov-east-1/vpc/cluster/eks-karpenter/terragrunt.hcl new file mode 100644 index 0000000..fc8d924 --- /dev/null +++ b/lab/us-gov-east-1/vpc/cluster/eks-karpenter/terragrunt.hcl @@ -0,0 +1,66 @@ +include "root" { + path = find_in_parent_folders("root.hcl") + merge_strategy = "deep" + expose = true +} + +locals { + # Skip this module if disabled + skip = !lookup(include.root.locals.is_module_enabled, basename(get_terragrunt_dir()), true) +} + +exclude { + if = local.skip + actions = ["all_except_output"] + exclude_dependencies = false +} + +terraform { + source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-karpenter.git?ref=${include.root.inputs.release_version}" + + extra_arguments "retry_lock" { + commands = get_terraform_commands_that_need_locking() + arguments = ["-lock-timeout=20s"] + } +} + +dependencies { + paths = [ + "../eks", + ] +} + +dependency "eks" { + config_path = "../eks" + mock_outputs_allowed_terraform_commands = ["init", "plan", "validate", "destroy"] + mock_outputs = { + cluster_name = "mock-cluster" + cluster_endpoint = "https://mock-endpoint.eks.amazonaws.com" + oidc_provider_arn = "arn:aws-us-gov:iam::123456789012:oidc-provider/mock" + node_group_name = "mock-node-group" + vpc_id = "vpc-mock" + subnets = ["subnet-mock1", "subnet-mock2"] + } +} + +inputs = { + # AWS Configuration + account_id = include.root.inputs.aws_account_id + profile = include.root.inputs.aws_profile + region = include.root.inputs.aws_region + eecr_info = include.root.inputs.eecr_info + + # Cluster Configuration + cluster_endpoint = dependency.eks.outputs.cluster_endpoint + cluster_name = dependency.eks.outputs.cluster_name + oidc_provider_arn = dependency.eks.outputs.oidc_provider_arn + vpc_id = dependency.eks.outputs.vpc_id + subnets = dependency.eks.outputs.subnets + + # Karpenter Configuration + karpenter_tag = include.root.inputs.karpenter_tag + karpenter_helm_chart = include.root.inputs.karpenter_helm_chart + karpenter_node_group_name = dependency.eks.outputs.node_group_name + namespace = include.root.inputs.namespaces["karpenter"] + create_spot_service_linked_role = false +} diff --git a/lab/us-gov-east-1/vpc/cluster/eks/terragrunt.hcl b/lab/us-gov-east-1/vpc/cluster/eks/terragrunt.hcl new file mode 100644 index 0000000..fd3787a --- /dev/null +++ b/lab/us-gov-east-1/vpc/cluster/eks/terragrunt.hcl @@ -0,0 +1,43 @@ +include "root" { + path = find_in_parent_folders("root.hcl") + merge_strategy = "deep" + expose = true +} + +locals { + # Skip this module if disabled + skip = !lookup(include.root.locals.is_module_enabled, basename(get_terragrunt_dir()), true) +} + +exclude { + if = local.skip + actions = ["all_except_output"] + exclude_dependencies = false +} + +terraform { + source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-eks.git?ref=${include.root.inputs.release_version}" + + extra_arguments "retry_lock" { + commands = get_terraform_commands_that_need_locking() + arguments = ["-lock-timeout=20s"] + } +} + +inputs = { + # AWS Configuration + account_id = include.root.inputs.aws_account_id + profile = include.root.inputs.aws_profile + region = include.root.inputs.aws_region + + # Core Cluster Configuration + cluster_name = include.root.inputs.cluster_name + cluster_version = include.root.inputs.cluster_version + eks_ng_desired_size = include.root.inputs.eks_ng_desired_size + eks_ng_max_size = include.root.inputs.eks_ng_max_size + eks_ng_min_size = include.root.inputs.eks_ng_min_size + eks_instance_types = ["t3a.large"] + + # Additional Configuration + tags = include.root.inputs.tags +} diff --git a/lab/us-gov-east-1/vpc/vpc.hcl b/lab/us-gov-east-1/vpc/vpc.hcl new file mode 100644 index 0000000..f0721a9 --- /dev/null +++ b/lab/us-gov-east-1/vpc/vpc.hcl @@ -0,0 +1,8 @@ +# lab/us-gov-east-1/vpc/vpc.hcl + +# Set VPC specific variables. These are automatically pulled in to configure the remote state bucket in the root +# terragrunt.hcl configuration. +locals { + vpc_name = "vpc3-lab-dev" + vpc_domain_name = "dev.lab.csp2.census.gov" +} diff --git a/root.hcl b/root.hcl new file mode 100644 index 0000000..5aa273b --- /dev/null +++ b/root.hcl @@ -0,0 +1,186 @@ +# ${environment}/root.hcl +# --------------------------------------------------------------------------------------------------------------------- +# TERRAGRUNT CONFIGURATION +# Terragrunt is a thin wrapper for Terraform that provides extra tools for working with multiple Terraform modules, +# remote state, and locking: https://github.com/gruntwork-io/terragrunt +# --------------------------------------------------------------------------------------------------------------------- +locals { + # Automatically load account-level variables (NOTE: In our environment account = environment so there is not separate environment layer) + account_vars = read_terragrunt_config(find_in_parent_folders("account.hcl")) + + # Automatically load cluster-level variables + cluster_vars = read_terragrunt_config(find_in_parent_folders("cluster.hcl")) + + # Automatically load _envcommon, cross account and environment common variables + common_vars = read_terragrunt_config(find_in_parent_folders("./_envcommon/common-variables.hcl")) + + # Automatically load naming prefixes + prefix_vars = read_terragrunt_config(find_in_parent_folders("./_envcommon/prefixes.hcl")) + + # Automatically load region-level variables + region_vars = read_terragrunt_config(find_in_parent_folders("region.hcl")) + + # Automatically load versions + versions = read_terragrunt_config(find_in_parent_folders("./_envcommon/default-versions.hcl")) + + # Automatically load vpc-level variables + vpc_vars = read_terragrunt_config(find_in_parent_folders("vpc.hcl")) + + # Add any other locals you want to expose + # only expose things not already included via local.xxx_vars.locals.* + root_locals_for_inputs = { + is_module_enabled = local.is_module_enabled + module_name = local.module_name + } + + # Extract the variables we need for easy access + account_id = local.account_vars.locals.aws_account_id + account_name = local.account_vars.locals.account_name + aws_profile = local.account_vars.locals.aws_profile + aws_region = local.region_vars.locals.aws_region + cluster_name = local.cluster_vars.locals.cluster_name + eecr_info = local.common_vars.locals.eecr_info + environment_abbr = local.common_vars.locals.environment_abbr + finops_project_name = local.cluster_vars.locals.finops_project_name + finops_project_number = local.cluster_vars.locals.finops_project_number + finops_project_role = local.cluster_vars.locals.finops_project_role + is_eks_module = local.module_name == "eks" ? true : false + prefixes = local.prefix_vars.locals.prefixes + is_module_enabled = merge( + { for module in local.versions.locals.core_modules : module => true }, + local.versions.locals.enabled_modules, + local.module_overrides + ) + module_name = basename(get_original_terragrunt_dir()) + module_overrides = local.cluster_vars.locals.module_enablement_overrides + organization = local.cluster_vars.locals.organization + state_bucket_prefix = local.common_vars.locals.state_bucket_prefix + state_table_name = local.common_vars.locals.state_table_name +} + +# Only generate providers for non-EKS modules +generate "cluster_data" { + path = "cluster-data.tf" + if_exists = "overwrite_terragrunt" + contents = local.is_eks_module ? "" : <<-EOF + data "aws_eks_clusters" "available" {} + + locals { + cluster_exists = contains(data.aws_eks_clusters.available.names, "${local.cluster_name}") + } + + data "aws_eks_cluster" "this" { + count = local.cluster_exists ? 1 : 0 + name = "${local.cluster_name}" + } + + data "aws_eks_cluster_auth" "this" { + count = local.cluster_exists ? 1 : 0 + name = "${local.cluster_name}" + } + EOF +} + +# Generate provider blocks only for non-EKS modules +generate "kube_provider" { + path = "kube-provider.tf" + if_exists = "overwrite_terragrunt" + contents = local.is_eks_module ? "" : <<-EOF + provider "kubernetes" { + host = local.cluster_exists ? data.aws_eks_cluster.this[0].endpoint : "https://dummy" + cluster_ca_certificate = local.cluster_exists ? base64decode(data.aws_eks_cluster.this[0].certificate_authority[0].data) : null + token = local.cluster_exists ? data.aws_eks_cluster_auth.this[0].token : "dummy" + } + EOF +} + +generate "helm_provider" { + path = "helm-provider.tf" + if_exists = "overwrite_terragrunt" + contents = local.is_eks_module ? "" : <<-EOF + provider "helm" { + kubernetes = { + host = local.cluster_exists ? data.aws_eks_cluster.this[0].endpoint : "https://dummy" + cluster_ca_certificate = local.cluster_exists ? base64decode(data.aws_eks_cluster.this[0].certificate_authority[0].data) : null + token = local.cluster_exists ? data.aws_eks_cluster_auth.this[0].token : "dummy" + } + } + EOF +} + +# Configure Terragrunt to automatically store tfstate files in an S3 bucket +remote_state { + disable_init = tobool(get_env("TG_DISABLE_INIT", "false")) + backend = "s3" + generate = { + path = "remote_state.backend.tf" + if_exists = "overwrite_terragrunt" + } + config = { + bucket = "${local.state_bucket_prefix}-${local.account_id}" + use_lockfile = true + key = "${trimprefix(replace(run_cmd("realpath", get_original_terragrunt_dir()), dirname(get_repo_root()), ""), "/")}/terraform.tfstate" + profile = "${local.aws_profile}" + region = "${local.aws_region}" + disable_bucket_update = true + } +} + +# Generate an AWS provider block +generate "aws-provider" { + path = "aws-provider.tf" + if_exists = "overwrite" + contents = <<-EOF + provider "aws" { + region = "${local.aws_region}" + profile = "${local.aws_profile}" + default_tags { + tags = { + cluster_name = "${local.cluster_name}" + "boc:module_name" = "${local.module_name}" + environment = "${local.environment_abbr}" + finops_project_name = "${local.finops_project_name}" + finops_project_number = "${local.finops_project_number}" + finops_project_role = "${local.finops_project_role}" + CostAllocation = "${local.CostAllocation}" + organization = "${local.organization}" + "boc:created-by" = "terragrunt" + } + } + # Only these AWS Account IDs may be operated on by this template + allowed_account_ids = ["${local.account_id}"] + } +EOF +} + +generate "tags-yml" { + path = "tags.yml" + if_exists = "overwrite" + contents = !local.is_eks_module ? "" : <<-EOF + finops: + number: "${tonumber(regex("[0-9]+$", local.finops_project_number))}" + name: "${local.finops_project_name}" + roles: + - eks + - "${local.finops_project_role}" + EOF +} + +# --------------------------------------------------------------------------------------------------------------------- +# GLOBAL PARAMETERS +# These variables apply to all configurations in this subfolder. These are automatically merged into the child +# `terragrunt.hcl` config via the include block. +# --------------------------------------------------------------------------------------------------------------------- + +# Configure root level variables that all resources can inherit. This is especially helpful with multi-account configs +# where terraform_remote_state data sources are placed directly into the modules. +inputs = merge( + local.account_vars.locals, + local.cluster_vars.locals, + local.common_vars.locals, + local.prefix_vars.locals, + local.region_vars.locals, + local.versions.locals, + local.vpc_vars.locals, + local.root_locals_for_inputs +)