From 78adde4dea0ba75d62212e1562f04b63418ac81d Mon Sep 17 00:00:00 2001 From: Matthew Creal Morgan Date: Wed, 25 Jun 2025 17:36:57 -0700 Subject: [PATCH] [Major] Code Freeze PR (#23) * yep * set back to normal * missed tempo * change branch ref to test provider-resolution * fix min vals * 2 is the lowest * docs and keycloak * use default for eks again * tempo and kiali updates while working on keycloak * almost * no v * cleanup * namespaces * use main * fmt * namespace changes * update internal url ref * fmt * versions * more wip: * keycloak wip * update prom internal url input value * test changes on prom * deleted old cluster platform-eng-eks-test and created new cluster platform-eng-eks-srn * testing more autoscaling stuffs * wip * wip * use my eks * otel added * ordering * test branch * removed a few folders from workspace * reset branches to default * missed one * fmt * use client id and secret * fix service name regex violation * updates * update from lukes pr * disable gatekeeper * updated * update eks module renaming * updated vars * revert dashboard stuff * update inputs * fix profile * latest * updated eks module version and sorted namespaces * update to pass account and regino * back to functional * initial arcgis module * fix ordering * add skip modules ability * add enterprise ecr stuff * fmt * wip * cross account pulls * updating readme (#22) * updating readme * Add initial README.md with project overview, structure, and usage instructions * Revise README.md for clarity and organization, enhancing descriptions of repository contents and usage instructions. * full cluster * clean up ws * fix profile and update versions * update ordering is istio is after otel * match the version in eecr * add otel * add image versions passthrough * fmt * move eecr data item to provider * pass ecr_info * dupe * add gatekeeper * add gatekeeper * add gatekeeper to workspace * update gatekeeper stuff * fmt * add keycloak_public_url * add discovery_url * fix enabled_modules ref * fix discovery_url source * add mock value to support run-all destroy after keycloak has been destroyed * update input_vars.hcl contents * use the right gatekeeper * fmt * add release versions map * add module_versions and dynamic lookup for release_version * rename release date * update karpenter version, fmt * fix(eks-gatekeeper): update inputs after module change * wip * update versions after merges * updated gatekeeper for plan * move buildspecs to buildspecs dir * python3.9 on this image * refactor pipeline stuff * min * turn pipeline back on * more wip * update * updated from tfmod-pipeline * add and delete for less git churn * add and delete for less git churn * add prefixes * add prefixes into locals context * add prefixes into root * add aws-logs output * add log tailing * update source strings to use https * central settings for codebuild * ssh stuff * wip * back to ssh * back to https now that network works * ssh again * https again * use a more recent image * add downloader * updates to state mgmt * testing * fmt * state issues * update to gitlab * wip * back to github * getting sboms * skip if in codebuild * cleanup/cruft removal * new cluster updates --------- Co-authored-by: Srini Nangunuri Co-authored-by: David John Arnold Jr --- .checkov.yml | 24 -- .github/platform-tg-infra.code-workspace | 42 +- Makefile | 108 ++++- README.md | 168 +++++--- configs/node-groups.yaml | 48 --- configs/resource-quotas.yml | 36 -- docs/Process.md | 334 +++++++++++++++ docs/enterprise_ecr_v1.drawio 1.png | Bin 0 -> 86062 bytes docs/terragrunt.stack.hcl.off | 380 ++++++++++++++++++ input_vars.hcl | 26 ++ lab/_envcommon/common-variables.hcl | 24 +- lab/_envcommon/default-versions.hcl | 161 ++++++-- lab/_envcommon/prefixes.hcl | 37 ++ lab/development/account.hcl | 2 +- .../vpc/csvd-platform-lab-mcm/cluster.hcl | 22 + .../eks-arcgis}/terragrunt.hcl | 66 +-- .../eks-cert-manager/terragrunt.hcl | 12 + .../eks-config/terragrunt.hcl | 23 +- .../eks-cribl}/terragrunt.hcl | 52 ++- .../eks-dns/terragrunt.hcl | 11 + .../eks-gatekeeper/terragrunt.hcl | 140 +++++++ .../eks-grafana/terragrunt.hcl | 25 +- .../eks-istio/terragrunt.hcl | 19 +- .../eks-k8s-dashboard/terragrunt.hcl | 12 + .../eks-karpenter/terragrunt.hcl | 12 + .../eks-keycloak/terragrunt.hcl | 24 +- .../eks-kiali/terragrunt.hcl | 39 +- .../eks-loki/terragrunt.hcl | 37 +- .../eks-metrics-server/terragrunt.hcl | 33 +- .../eks-otel/terragrunt.hcl | 48 ++- .../eks-pipeline/terragrunt.hcl | 100 +++++ .../eks-prometheus/README.md | 0 .../eks-prometheus/terragrunt.hcl | 13 + .../eks-tempo/terragrunt.hcl | 12 + .../eks/terragrunt.hcl | 17 + .../vpc/platform-eng-eks-mcm/cluster.hcl | 28 -- .../eks-gogatekeeper/terragrunt.hcl.off | 80 ---- .../eks-loki/terragrunt.hcl | 55 --- .../eks-metrics-server/terragrunt.hcl | 42 -- .../vpc/platform-eng-eks-srn/cluster.hcl | 28 -- .../eks-cert-manager/terragrunt.hcl | 57 --- .../eks-dns/terragrunt.hcl | 60 --- .../eks-grafana/terragrunt.hcl | 63 --- .../eks-istio/terragrunt.hcl | 44 -- .../eks-k8s-dashboard/terragrunt.hcl | 55 --- .../eks-karpenter/terragrunt.hcl | 50 --- .../eks-keycloak/terragrunt.hcl | 87 ---- .../eks-kiali/terragrunt.hcl | 113 ------ .../eks-kiali/terragrunt.hcl.disabled | 108 ----- .../eks-prometheus/README.md | 198 --------- .../eks-prometheus/terragrunt.hcl | 61 --- .../eks-tempo/terragrunt.hcl | 66 --- .../platform-eng-eks-srn/eks/terragrunt.hcl | 28 -- .../vpc/platform-test-cicd/cluster.hcl | 20 - .../eks-cert-manager/terragrunt.hcl | 40 -- .../eks-config/terragrunt.hcl | 42 -- .../platform-test-cicd/eks-dns/terragrunt.hcl | 42 -- .../eks-grafana/terragrunt.hcl | 40 -- .../eks-istio/terragrunt.hcl | 32 -- .../eks-k8s-dashboard/terragrunt.hcl | 36 -- .../eks-karpenter/terragrunt.hcl | 43 -- .../eks-kiali/terragrunt.hcl.disable | 81 ---- .../eks-loki/terragrunt.hcl | 44 -- .../eks-metrics-server/terragrunt.hcl | 33 -- .../eks-prometheus/README.md | 198 --------- .../eks-prometheus/terragrunt.hcl | 38 -- .../eks-tempo/terragrunt.hcl | 46 --- .../vpc/platform-test-cicd/eks/terragrunt.hcl | 56 --- .../vpc/platform-test-x/cluster.hcl | 20 - .../vpc/platform-test-z/cluster.hcl | 21 - .../eks-alloy-disable/terragrunt.hcl.disable | 27 -- .../eks-cert-manager/terragrunt.hcl | 57 --- .../platform-test-z/eks-config/terragrunt.hcl | 54 --- .../platform-test-z/eks-dns/terragrunt.hcl | 61 --- .../eks-grafana/terragrunt.hcl | 81 ---- .../platform-test-z/eks-istio/terragrunt.hcl | 45 --- .../eks-k8s-dashboard/terragrunt.hcl | 46 --- .../eks-karpenter/terragrunt.hcl | 49 --- .../platform-test-z/eks-kiali/terragrunt.hcl | 91 ----- .../platform-test-z/eks-loki/terragrunt.hcl | 48 --- .../eks-metrics-server/terragrunt.hcl | 44 -- .../eks-open-telemetry/terragrunt.hcl | 61 --- .../platform-test-z/eks-prometheus/README.md | 198 --------- .../eks-prometheus/terragrunt.hcl | 40 -- .../platform-test-z/eks-tempo/terragrunt.hcl | 47 --- .../vpc/platform-test-z/eks/terragrunt.hcl | 28 -- lab/root.hcl | 75 ++-- notes.md | 78 ---- plan.md | 271 ------------- 89 files changed, 1825 insertions(+), 3738 deletions(-) delete mode 100644 .checkov.yml delete mode 100644 configs/node-groups.yaml delete mode 100644 configs/resource-quotas.yml create mode 100644 docs/Process.md create mode 100644 docs/enterprise_ecr_v1.drawio 1.png create mode 100644 docs/terragrunt.stack.hcl.off create mode 100644 input_vars.hcl create mode 100644 lab/_envcommon/prefixes.hcl create mode 100644 lab/development/us-gov-east-1/vpc/csvd-platform-lab-mcm/cluster.hcl rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-srn/eks-postgresql => csvd-platform-lab-mcm/eks-arcgis}/terragrunt.hcl (55%) rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-mcm => csvd-platform-lab-mcm}/eks-cert-manager/terragrunt.hcl (86%) rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-mcm => csvd-platform-lab-mcm}/eks-config/terragrunt.hcl (89%) rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-srn/eks-config => csvd-platform-lab-mcm/eks-cribl}/terragrunt.hcl (62%) rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-mcm => csvd-platform-lab-mcm}/eks-dns/terragrunt.hcl (86%) create mode 100644 lab/development/us-gov-east-1/vpc/csvd-platform-lab-mcm/eks-gatekeeper/terragrunt.hcl rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-mcm => csvd-platform-lab-mcm}/eks-grafana/terragrunt.hcl (82%) rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-mcm => csvd-platform-lab-mcm}/eks-istio/terragrunt.hcl (69%) rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-mcm => csvd-platform-lab-mcm}/eks-k8s-dashboard/terragrunt.hcl (84%) rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-mcm => csvd-platform-lab-mcm}/eks-karpenter/terragrunt.hcl (84%) rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-mcm => csvd-platform-lab-mcm}/eks-keycloak/terragrunt.hcl (79%) rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-mcm => csvd-platform-lab-mcm}/eks-kiali/terragrunt.hcl (79%) rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-srn => csvd-platform-lab-mcm}/eks-loki/terragrunt.hcl (83%) rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-srn => csvd-platform-lab-mcm}/eks-metrics-server/terragrunt.hcl (79%) rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-mcm => csvd-platform-lab-mcm}/eks-otel/terragrunt.hcl (58%) create mode 100644 lab/development/us-gov-east-1/vpc/csvd-platform-lab-mcm/eks-pipeline/terragrunt.hcl rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-mcm => csvd-platform-lab-mcm}/eks-prometheus/README.md (100%) rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-mcm => csvd-platform-lab-mcm}/eks-prometheus/terragrunt.hcl (86%) rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-mcm => csvd-platform-lab-mcm}/eks-tempo/terragrunt.hcl (86%) rename lab/development/us-gov-east-1/vpc/{platform-eng-eks-mcm => csvd-platform-lab-mcm}/eks/terragrunt.hcl (70%) delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-mcm/cluster.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-mcm/eks-gogatekeeper/terragrunt.hcl.off delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-mcm/eks-loki/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-mcm/eks-metrics-server/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/cluster.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-cert-manager/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-dns/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-grafana/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-istio/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-k8s-dashboard/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-karpenter/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-keycloak/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-kiali/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-kiali/terragrunt.hcl.disabled delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-prometheus/README.md delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-prometheus/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-tempo/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-cicd/cluster.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-cert-manager/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-config/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-dns/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-grafana/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-istio/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-k8s-dashboard/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-karpenter/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-kiali/terragrunt.hcl.disable delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-loki/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-metrics-server/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-prometheus/README.md delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-prometheus/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-tempo/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-cicd/eks/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-x/cluster.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-z/cluster.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-z/eks-alloy-disable/terragrunt.hcl.disable delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-z/eks-cert-manager/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-z/eks-config/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-z/eks-dns/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-z/eks-grafana/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-z/eks-istio/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-z/eks-k8s-dashboard/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-z/eks-karpenter/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-z/eks-kiali/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-z/eks-loki/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-z/eks-metrics-server/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-z/eks-open-telemetry/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-z/eks-prometheus/README.md delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-z/eks-prometheus/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-z/eks-tempo/terragrunt.hcl delete mode 100644 lab/development/us-gov-east-1/vpc/platform-test-z/eks/terragrunt.hcl delete mode 100644 notes.md delete mode 100644 plan.md diff --git a/.checkov.yml b/.checkov.yml deleted file mode 100644 index cc000299..00000000 --- a/.checkov.yml +++ /dev/null @@ -1,24 +0,0 @@ -branch: master -download-external-modules: true -evaluate-variables: true -external-checks-dir: - - security/custom_checks -framework: - - terraform - - kubernetes -output: - - cli - - json - - junitxml -skip-check: - - CKV_AWS_79 # Instance Metadata Service Version 1 - - CKV_AWS_130 # Ensure VPC subnets are not assigned public IP by default -quiet: true -compact: true -directory: - - . - - modules/* -secrets-scan-file-type: - - tf - - yaml - - json diff --git a/.github/platform-tg-infra.code-workspace b/.github/platform-tg-infra.code-workspace index d243b5d4..05b26aa5 100644 --- a/.github/platform-tg-infra.code-workspace +++ b/.github/platform-tg-infra.code-workspace @@ -8,6 +8,22 @@ "name": "tfmod-cert-mgr", "path": "../../tfmod-cert-mgr" }, + { + "name": "tfmod-config-job", + "path": "../../tfmod-config-job" + }, + { + "name": "tfmod-cribl", + "path": "../../tfmod-cribl" + }, + { + "name": "tfmod-custom-iam-role-for-service-account-eks", + "path": "../../tfmod-custom-iam-role-for-service-account-eks" + }, + { + "name": "tfmod-downloader", + "path": "../../tfmod-downloader" + }, { "name": "tfmod-eks", "path": "../../tfmod-eks" @@ -21,8 +37,12 @@ "path": "../../tfmod-eks-dns" }, { - "name": "tfmod-gogatekeeper", - "path": "../../tfmod-gogatekeeper" + "name": "tfmod-esri-arcgis", + "path": "../../tfmod-esri-arcgis" + }, + { + "name": "tfmod-gatekeeper", + "path": "../../tfmod-gatekeeper" }, { "name": "tfmod-grafana", @@ -65,23 +85,23 @@ "path": "../../tfmod-open-telemetry" }, { - "name": "tfmod-prometheus", - "path": "../../tfmod-prometheus" + "name": "tfmod-pipeline", + "path": "../../tfmod-pipeline" }, { - "name": "tfmod-tempo", - "path": "../../tfmod-tempo" + "name": "tfmod-prometheus", + "path": "../../tfmod-prometheus" }, { - "name": "terraform-aws-eks", - "path": "../../terraform-aws-eks" + "name": "tfmod-postgresql", + "path": "../../tfmod-postgresql" }, { - "name": "terragrunt", - "path": "../../terragrunt" + "name": "tfmod-tempo", + "path": "../../tfmod-tempo" }, { - "path": "../../tfmod-config-job" + "path": "../../repo-setup" } ] } diff --git a/Makefile b/Makefile index fc196a2c..83b9dcca 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,8 @@ -.PHONY: help init validate plan fmt check clean +.PHONY: help config init validate plan fmt check clean deploy-to-pipeline tail parse +# Default values +ENV ?= development +REGION_DIR ?= us-gov-east-1 +CLUSTER_DIR ?= csvd-platform-lab-mcm help: @echo "Available targets:" @@ -8,7 +12,62 @@ help: @echo " fmt - Format HCL files" @echo " check - Run all checks (format, validate, plan)" @echo " clean - Clean up Terragrunt cache and temporary files" + @echo " deploy-to-pipeline - Zip and upload to S3 to trigger CodePipeline" + @echo " tail - Tail the logs of the CodeBuild project" +# Shared configuration target that exports all variables +config: + @echo "Loading configuration..." + +# Detect configuration files + $(eval ACCOUNT_HCL=lab/$(ENV)/account.hcl) + $(eval REGION_HCL=lab/$(ENV)/$(REGION_DIR)/region.hcl) + $(eval CLUSTER_HCL=lab/$(ENV)/$(REGION_DIR)/vpc/$(CLUSTER_DIR)/cluster.hcl) + + @if [ ! -f "$(ACCOUNT_HCL)" ]; then echo "Error: $(ACCOUNT_HCL) not found"; exit 1; fi + @if [ ! -f "$(REGION_HCL)" ]; then echo "Error: $(REGION_HCL) not found"; exit 1; fi + @if [ ! -f "$(CLUSTER_HCL)" ]; then echo "Error: $(CLUSTER_HCL) not found"; exit 1; fi + +# Extract values from HCL files + $(eval AWS_ACCOUNT_ID=$(shell grep -oP 'aws_account_id\s*=\s*"\K[^"]+' $(ACCOUNT_HCL))) + $(eval ACCOUNT_NAME=$(shell grep -oP 'account_name\s*=\s*"\K[^"]+' $(ACCOUNT_HCL))) + $(eval AWS_PROFILE=$(shell echo $(AWS_ACCOUNT_ID)-$(shell echo $(ACCOUNT_NAME) | sed 's/-ew/-gov/'))) + $(eval AWS_REGION=$(shell grep -oP 'aws_region\s*=\s*"\K[^"]+' $(REGION_HCL))) + $(eval CLUSTER_NAME=$(shell grep -oP 'cluster_name\s*=\s*"\K[^"]+' $(CLUSTER_HCL))) + +# Calculate derived values + $(eval REGION_SHORT=$(shell echo $(AWS_REGION) | sed 's/\([a-z]\)[a-z]*-/\1/g')) + $(eval S3_BUCKET=v-s3-eks-$(CLUSTER_NAME)-artifacts-$(AWS_ACCOUNT_ID)-$(REGION_SHORT)) + $(eval OBJECT_KEY=clusters/$(CLUSTER_NAME)/platform-tg-infra.zip) + $(eval PIPELINE_NAME=eks-$(CLUSTER_NAME)-codepipeline) + $(eval PIPELINE_URL=https://console.amazonaws-us-gov.com/codesuite/codepipeline/pipelines/$(PIPELINE_NAME)/view?region=$(AWS_REGION)) + + @echo "Using configuration:" + @echo " AWS_ACCOUNT_ID: $(AWS_ACCOUNT_ID)" + @echo " ACCOUNT_NAME: $(ACCOUNT_NAME)" + @echo " AWS_PROFILE: $(AWS_PROFILE)" + @echo " AWS_REGION: $(AWS_REGION)" + @echo " CLUSTER_NAME: $(CLUSTER_NAME)" + @echo " S3_BUCKET: $(S3_BUCKET)" + + @if [ -z "$(AWS_ACCOUNT_ID)" ] || [ -z "$(AWS_PROFILE)" ] || [ -z "$(AWS_REGION)" ] || [ -z "$(CLUSTER_NAME)" ]; then \ + echo "Error: Failed to extract all required variables from HCL files"; \ + exit 1; \ + fi + +# Export variables for child processes + $(eval export AWS_ACCOUNT_ID) + $(eval export ACCOUNT_NAME) + $(eval export AWS_PROFILE) + $(eval export AWS_REGION) + $(eval export CLUSTER_NAME) + $(eval export REGION_SHORT) + $(eval export S3_BUCKET) + $(eval export OBJECT_KEY) + $(eval export PIPELINE_NAME) + $(eval export PIPELINE_URL) + +# Basic terragrunt operations init: @echo "Initializing Terragrunt configurations..." terragrunt run-all init @@ -33,3 +92,50 @@ clean: find . -type d -name ".terragrunt-cache" -exec rm -rf {} + find . -type f -name ".terraform.lock.hcl" -delete find . -type f -name "terragrunt-debug.tfvars.json" -delete + +# Pipeline operations that depend on shared config +deploy-to-pipeline: config + @echo "Preparing to deploy to pipeline..." + + @echo "Copy buildspecs from tfmod-pipeline" + mkdir -p ./buildspecs + cp -r ../tfmod-pipeline/buildspecs/* ./buildspecs + + @echo "Creating zip file..." + zip -r platform-tg-infra.zip . -x "*.git*" "*.github*" "*.terragrunt-cache*" "*.terraform*" + + rm -rf ./buildspecs + + @echo "Stopping any active pipeline executions for $(PIPELINE_NAME)..." + $(eval PIPELINE_EXECUTIONS=$(shell aws codepipeline list-pipeline-executions --pipeline-name $(PIPELINE_NAME) --region $(AWS_REGION) --profile $(AWS_PROFILE) --query "pipelineExecutionSummaries[?status=='InProgress'].pipelineExecutionId" --output text)) + @if [ -n "$(PIPELINE_EXECUTIONS)" ]; then \ + echo "Found active pipeline executions: $(PIPELINE_EXECUTIONS)"; \ + for EXECUTION_ID in $(PIPELINE_EXECUTIONS); do \ + echo "Stopping execution $$EXECUTION_ID..."; \ + aws codepipeline stop-pipeline-execution --pipeline-name $(PIPELINE_NAME) --pipeline-execution-id $$EXECUTION_ID --region $(AWS_REGION) --profile $(AWS_PROFILE) --abandon || echo "Warning: Failed to stop execution $$EXECUTION_ID"; \ + done; \ + echo "Waiting for pipeline executions to stop (10 seconds)..."; \ + sleep 10; \ + else \ + echo "No active pipeline executions found."; \ + fi + + @echo "Uploading to S3 bucket $(S3_BUCKET)..." + aws s3 cp platform-tg-infra.zip s3://$(S3_BUCKET)/$(OBJECT_KEY) --profile $(AWS_PROFILE) --sse aws:kms + @echo "Upload complete. Pipeline should trigger automatically." + rm -f platform-tg-infra.zip + + @echo "Pipeline URL: $(PIPELINE_URL)" + @echo "You can access the pipeline directly at the URL above." + @echo "Logs will start once CodeBuild runs... this can take a few minutes..." + $(MAKE) tail + +# Improved tail action using shared config +tail: config + @echo "Tailing Pipeline Logs for cluster $(CLUSTER_NAME):" + aws logs tail /aws/codebuild/$(CLUSTER_NAME) \ + --format short \ + --follow \ + --since 1m \ + --region $(AWS_REGION) \ + --profile $(AWS_PROFILE) diff --git a/README.md b/README.md index 454f6c3a..248d122a 100644 --- a/README.md +++ b/README.md @@ -1,55 +1,115 @@ -## How to setup and run terragrunt scripts for EKS related modules in a LAB account - -### Lab Account request and setup: - - Open a REMEDY ticket for creating an account in LAB environment, preferably with t3-admin role. - - LAB account url:https://pssvlab.tco.census.gov/PSS/ - - Make a note that the LAB account password is different from laptop password - - Once you have successful log proceed to next steps below - -### Access LAB jumphost (bromine): - Refer this page for additional help on sso credentials: https://github.e.it.census.gov/terraform/support/tree/master/docs/how-to/aws-sso - - 1. Goto LAB workspace:https://clients.amazonworkspaces.com/ - 2. Hit the web access login on the top right corner - 3. Enter the following registration code: FRosu+FMEXNZ and click Register - 4. Use your jbid and password (use lab password) - 5. Open reflection client and ssh connect to bromine.cto.census.gov - 6. On bromine, sso login to lab-gov as: - $ aws-sso-login.sh lab-gov - 7. On a browser goto auth-dev.census.gov - 8. Use PIV card option to login - 9. Copy the link from step 6 and paste it on the portal and authenticate - 10. Go back to bromine and doubleclick at an empty space, you should get successful login lab env - -### Environment Setup: - - Set your profile as a default profile by exporting AWS_PROFILE variable - $ export AWS_PROFILE="224384469011-lab-dev-gov.inf-admin-t3" - $ aws sts get-caller-identity - - Run any aws commands to make sure you are getting responses from the account your profile is set to: - $ aws s3 ls - -### Terraform/Terragrunt binaries and versions: - The following binaries used: - - Terraform version: v1.7.5 - - Terragrunt version: v0.55.21 - These versions can be found on bromine.cto.census.gov host at: - /app/terraform/bin/terr* folder - -### Run the Terragrunt script: - - Cd to specifc folder (example: cd eks) and Run terragrunt plan - $ terragrunt plan - - Verify the plan output and make sure there are no errors - - Run terragrunt apply - $ terragrunt apply - - Verify apply completes successfully and verify the resources on AWS Console. - -### Accessing the cluster: - $ aws eks --region us-gov-east-1 update-kubeconfig --name platform-eng-eks-test - $ kubectl config use-context arn:aws-us-gov:eks:us-gov-east-1:224384469011:cluster/platform-eng-eks-test - $ kubectl config get-contexts - -### Run few kubectl commands to verify you are accessing the cluster - $ kubectl cluster-info - $ kubectl get pods -A - $ kubectl get ns +# Platform Infrastructure with Terragrunt +This repository helps manage cloud infrastructure using Terragrunt. It is designed to make managing infrastructure easier and more organized. Terragrunt is used to handle infrastructure as code for different environments. + +## What's in This Repository + +- `/configs` - Files for setting up things like node groups and resource limits +- `/docs` - Guides and rules for how to set up and manage the infrastructure +- `/lab` - Settings for testing and development environments +- `/monitoring` - Tools for keeping an eye on the system +- `/tests` - Tests to make sure everything works as expected + +## Documentation + +You can find detailed guides in the `/docs` folder: + +- [Architecture](docs/ARCHITECTURE.md) - How the system is built +- [Documentation Standards](docs/DOCUMENTATION_STANDARDS.md) - How to write good documentation +- [Infrastructure Standards](docs/INFRASTRUCTURE_STANDARDS.md) - Rules for setting up infrastructure +- [Module Dependencies](docs/MODULE_DEPENDENCIES.md) - How different parts depend on each other +- [Module Standards](docs/MODULE_STANDARDS.md) - Rules for creating modules +- [Observability Standards](docs/OBSERVABILITY_STANDARDS.md) - How to monitor the system +- [Security Audit Checklist](docs/SECURITY_AUDIT_CHECKLIST.md) - Steps to check for security issues +- [Security Baseline](docs/SECURITY_BASELINE.md) - Basic security requirements +- [Testing Standards](docs/TESTING_STANDARDS.md) - Rules for testing +- [Version Control](docs/VERSION_CONTROL.md) - How to manage code versions + +## What You Need + +- Terraform v1.0.0 or newer +- Terragrunt v0.36.0 or newer +- AWS CLI set up with the right permissions +- Access to AWS resources + +## How to Get Started + +### Using the Makefile + +This repository has a Makefile with helpful commands: + +```bash +make help # See available commands +make init # Set up Terragrunt +make validate # Check if everything is set up correctly +make plan # Preview changes +make fmt # Format files +make check # Run all checks +make clean # Clean up temporary files +``` + +### Manual Terragrunt Commands + +Go to the folder with the Terragrunt configuration you want to use: + +```bash +cd lab/environment/component + +# Set up Terragrunt +terragrunt init + +# Preview changes +terragrunt plan + +# Apply changes +terragrunt apply + +# Remove resources +terragrunt destroy +``` + +### Running All Configurations + +Run commands for all Terragrunt configurations: + +```bash +# Set up everything +terragrunt run-all init + +# Preview all changes +terragrunt run-all plan + +# Apply all changes +terragrunt run-all apply +``` + +## Configuration + +Terragrunt configurations are organized like this: + +1. Main settings for each environment +2. Specific settings for different parts of the system +3. Overrides for special cases + +Check the environment folders for more details. + +## Testing + +The `/tests` folder has tools to check if everything works. To run tests: + +```bash +cd tests +./run_tests.sh +``` + +## How to Contribute + +1. Make a copy of this repository +2. Create a new branch for your changes +3. Make your updates +4. Run `make check` to ensure everything is correct +5. Submit a pull request + +## License + +Copyright © 2025 Your Organization. All rights reserved. diff --git a/configs/node-groups.yaml b/configs/node-groups.yaml deleted file mode 100644 index 11e09cad..00000000 --- a/configs/node-groups.yaml +++ /dev/null @@ -1,48 +0,0 @@ -nodeGroups: - - name: general-purpose - instanceTypes: - - m6i.xlarge - - m6a.xlarge - - m5.xlarge - minSize: 2 - maxSize: 10 - desiredSize: 2 - labels: - node-type: general - taints: [] - updateConfig: - maxUnavailable: 1 - - - name: compute-optimized - instanceTypes: - - c6i.2xlarge - - c6a.2xlarge - - c5.2xlarge - minSize: 1 - maxSize: 20 - desiredSize: 2 - labels: - node-type: compute - taints: - - key: workload - value: batch - effect: NoSchedule - updateConfig: - maxUnavailable: 2 - - - name: memory-optimized - instanceTypes: - - r6i.2xlarge - - r6a.2xlarge - - r5.2xlarge - minSize: 1 - maxSize: 10 - desiredSize: 2 - labels: - node-type: memory - taints: - - key: workload - value: memory-intensive - effect: NoSchedule - updateConfig: - maxUnavailable: 1 diff --git a/configs/resource-quotas.yml b/configs/resource-quotas.yml deleted file mode 100644 index 655595d0..00000000 --- a/configs/resource-quotas.yml +++ /dev/null @@ -1,36 +0,0 @@ -apiVersion: v1 -kind: ResourceQuota -metadata: - name: default-quota -spec: - hard: - requests.cpu: "20" - requests.memory: 40Gi - limits.cpu: "40" - limits.memory: 80Gi - pods: "100" - services: "50" - secrets: "100" - configmaps: "100" - persistentvolumeclaims: "50" - ---- -apiVersion: v1 -kind: LimitRange -metadata: - name: default-limits -spec: - limits: - - type: Container - default: - cpu: 500m - memory: 512Mi - defaultRequest: - cpu: 100m - memory: 256Mi - max: - cpu: "4" - memory: 8Gi - min: - cpu: 50m - memory: 64Mi diff --git a/docs/Process.md b/docs/Process.md new file mode 100644 index 00000000..ebfdd154 --- /dev/null +++ b/docs/Process.md @@ -0,0 +1,334 @@ +# Terraform Module Execution Process + +This document outlines the step-by-step process flow of our Terraform modules, explaining what each module does and the resources it creates. + +## 1. Pipeline Setup (tfmod-pipeline) + +**Purpose**: Creates the CI/CD infrastructure to build, plan, and apply the rest of the Terraform modules. + +**Resources Created**: +- AWS CodePipeline +- AWS CodeBuild projects +- IAM roles and policies for pipeline execution +- S3 buckets for artifacts +- CloudWatch event rules for pipeline triggers + +## 2. Core Infrastructure + +### 2.1 EKS Cluster (tfmod-eks) + +**Purpose**: Creates a managed Kubernetes cluster in AWS. + +**Resources Created**: +- EKS cluster +- EKS node groups +- VPC (if not using existing) +- Security groups +- IAM roles for EKS service and node groups + +### 2.2 EKS Configuration (tfmod-eks-configuration) + +**Purpose**: Configures the EKS cluster with essential settings. + +**Resources Created**: +- Kubernetes namespaces +- Service accounts +- RBAC configurations +- Add-on prerequisites + +### 2.3 Custom IAM Roles for Service Accounts (tfmod-custom-iam-role-for-service-account-eks) + +**Purpose**: Sets up IAM roles that can be assumed by Kubernetes service accounts via IRSA. + +**Resources Created**: +- IAM roles +- IAM policies +- Trust relationships + +### 2.4 EKS DNS Configuration (tfmod-eks-dns) + +**Purpose**: Configures DNS settings for the cluster. + +**Resources Created**: +- Route53 records +- DNS-related Kubernetes resources + +## 3. Cluster Monitoring & Observability + +### 3.1 Metrics Server (tfmod-metrics-server) + +**Purpose**: Deploys the Kubernetes Metrics Server for resource metrics. + +**Resources Created**: +- Metrics Server deployment +- Related service accounts and RBAC + +### 3.2 Prometheus (tfmod-prometheus) + +**Purpose**: Sets up Prometheus for metrics collection and alerting. + +**Resources Created**: +- Prometheus server +- Alert manager +- Service monitors +- Related Kubernetes resources + +### 3.3 Grafana (tfmod-grafana) + +**Purpose**: Deploys Grafana for metrics visualization. + +**Resources Created**: +- Grafana deployment +- Dashboards +- Data sources configuration + +### 3.4 Loki (tfmod-loki) + +**Purpose**: Implements log aggregation for the cluster. + +**Resources Created**: +- Loki deployment +- Log aggregation components +- Storage configuration + +### 3.5 Tempo (tfmod-tempo) + +**Purpose**: Provides distributed tracing capabilities. + +**Resources Created**: +- Tempo deployment +- Tracing components +- Storage configuration + +### 3.6 Open Telemetry (tfmod-open-telemetry) + +**Purpose**: Implements the OpenTelemetry collector for observability data. + +**Resources Created**: +- OpenTelemetry collector +- Configuration for metrics, logs, and traces + +### 3.7 Cribl (tfmod-cribl) + +**Purpose**: Deploys Cribl for log processing and forwarding. + +**Resources Created**: +- Cribl deployment +- Processing rules +- Output destinations + +## 4. Service Mesh & API Management + +### 4.1 Istio (tfmod-istio) + +**Purpose**: Implements a service mesh for the cluster. + +**Resources Created**: +- Istio control plane +- Istio gateways +- CRDs and operators + +### 4.2 Istio Service Ingress (tfmod-istio-service-ingress) + +**Purpose**: Configures ingress resources using Istio. + +**Resources Created**: +- Virtual services +- Gateways +- Service entries + +### 4.3 Kiali (tfmod-kiali) + +**Purpose**: Deploys Kiali for visualizing the service mesh. + +**Resources Created**: +- Kiali deployment +- Service +- Dashboard configuration + +## 5. Security & Compliance + +### 5.1 Cert Manager (tfmod-cert-mgr) + +**Purpose**: Manages certificates within the Kubernetes cluster. + +**Resources Created**: +- Cert-manager deployment +- CRDs for certificate resources +- Issuers/ClusterIssuers + +### 5.2 Gatekeeper (tfmod-gatekeeper) + +**Purpose**: Implements policy enforcement and governance. + +**Resources Created**: +- OPA Gatekeeper deployment +- Constraint templates +- Constraints + +## 6. Database & Persistent Storage + +### 6.1 PostgreSQL (tfmod-postgresql) + +**Purpose**: Deploys PostgreSQL database instances. + +**Resources Created**: +- PostgreSQL deployment or AWS RDS instances +- Storage configuration +- Network policies + +## 7. Application-Specific Modules + +### 7.1 Config Jobs (tfmod-config-job) + +**Purpose**: Creates Kubernetes jobs for configuration tasks. + +**Resources Created**: +- Kubernetes jobs +- ConfigMaps +- Secrets + +### 7.2 Keycloak (tfmod-keycloak) + +**Purpose**: Deploys Keycloak for identity and access management. + +**Resources Created**: +- Keycloak deployment +- Persistent storage +- Ingress configuration + +### 7.3 Kubernetes Dashboard (tfmod-k8s-dashboard) + +**Purpose**: Provides a web UI for the Kubernetes cluster. + +**Resources Created**: +- Dashboard deployment +- Service account +- RBAC configuration + +### 7.4 ArcGIS (tfmod-esri-arcgis) + +**Purpose**: Deploys ArcGIS services on the cluster. + +**Resources Created**: +- ArcGIS deployments +- Services +- Storage configuration + +### 7.5 Karpenter (tfmod-karpenter) + +**Purpose**: Implements Karpenter for Kubernetes node provisioning. + +**Resources Created**: +- Karpenter controller +- Provisioner CRDs +- Node templates + +## Execution Flow + +The modules are typically executed in the order outlined above, with the pipeline module orchestrating the process: + +1. The pipeline is created first (manually or by another automation) + - **Consolidated Image Security Processing**: A single security stage processes all container images used across modules: + - Image inventory collection from all module configurations + - Batch processing of vulnerability scanning + - Central SBOM (Software Bill of Materials) repository + - Single signing authority for all images + - Creation of a security compliance registry +2. Core infrastructure is established +3. Monitoring and observability tools are deployed +4. Service mesh and security components are added +5. Database and application-specific modules are deployed + +Each module depends on resources created by previous modules, forming a dependency chain that ensures proper infrastructure creation. + +## Image Security Implementation + +Container image security is implemented as a consolidated phase within the tfmod-pipeline module: + +- **Image Inventory**: Extracts container image references from all module configurations before deployment begins +- **Centralized Processing**: Processes all unique images in parallel rather than per-module +- **Security Registry**: Creates a compliance database that tracks security status of each image +- **Verification API**: Provides a lightweight API for modules to verify image compliance at deployment time +- **Policy Enforcement**: Blocks deployment of any module referencing non-compliant images + +### Image Inventory Collection Implementation + +The image inventory collection is implemented as part of the existing security stage in the pipeline: + +1. **Security Stage Enhancement**: + - The current security stage is expanded to include image security processing + - This maintains the existing pipeline structure (source → build → security → approve → deploy) + - No additional pipeline stages are required + +2. **Security Stage Sub-steps**: + - **Infrastructure Security**: Original security checks for IAC (continues as is) + - **Image Inventory**: Runs `terragrunt plan -json` for all modules to extract image references + - **Image Security Processing**: Scans, generates SBOMs, and signs images + - All vulnerabilities are automatically reported to AWS Security Hub + - Findings include image details, CVE IDs, severity levels, and remediation guidance + - **Security Registry Update**: Records compliance status of all images + - Security Hub findings are linked to the compliance database + - Security Hub integration enables centralized vulnerability management + +3. **Implementation Process**: + - CodeBuild job in the security stage collects Terraform plans + - Parsing script extracts image references from plan outputs + - Each unique image undergoes security checks in parallel + - Results are stored in a central compliance database + - Security Hub receives all vulnerability findings with proper resource tagging + - Final step generates a compliance report showing pass/fail status for all images + +4. **Pre-approval Check**: + - Before the approval stage, a validation step confirms all images are compliant + - Non-compliant images trigger pipeline warnings or failures based on policy settings + - Compliance summary is included in the approval notification + - Links to Security Hub findings are provided in notifications + +## Image Security Tooling + +The following tools are recommended for each phase of the image security process: + +### 1. Image Inventory Collection +- **Terragrunt/Terraform**: Using `terragrunt plan -json` output +- **jq/Python**: For parsing plan outputs to extract image references +- **AWS CodeBuild**: Custom build step with extraction script + +### 2. Vulnerability Scanning +- **AWS ECR Enhanced Scanning**: Primary scanning engine for ECR images +- **Trivy**: Open-source scanner for comprehensive vulnerability detection +- **Amazon Inspector**: For deeper AWS-integrated scanning and compliance reporting + +### 3. SBOM Generation +- **AWS SBOM Generator**: Native AWS tool for ECR images +- **CycloneDX/SPDX**: Standard formats for storing SBOM data + +### 4. Image Signing +- **Cosign**: For signing container images with simple keys or KMS +- **AWS Signer**: For AWS-managed signing workflows + +### 5. Security Data Management +- **AWS Security Hub**: Primary repository for all vulnerability findings + - Serves as the source of truth for security findings + - Provides organization-wide visibility and reporting + - Enables centralized policy management and alerting + +- **Pipeline-specific Database** (DynamoDB): + - Lightweight lookup table for CI/CD processes only + - Maps images to modules for deployment decisions + - Stores pipeline-specific metadata not relevant to Security Hub + - Contains links to Security Hub findings rather than duplicating data + - Enables fast deployment-time checks without querying Security Hub APIs + +This separation ensures Security Hub remains the authoritative source for security data while the pipeline database only stores what's needed for efficient CI/CD operations. + +### 6. Security Hub Integration +- **AWS Security Hub Custom Findings**: For publishing vulnerability data +- **AWS EventBridge**: For automating notifications and remediation +- **AWS Lambda**: For findings enrichment and customized reporting + +The security stage configures these tools as needed and orchestrates their execution in the proper sequence to provide a comprehensive security posture for all container images. + +This approach leverages the existing pipeline structure while ensuring all container images are properly secured before deployment. + +This approach is more reliable than static code parsing since it works with the exact resolved values that Terraform will use during deployment, including all variable substitutions and dynamic values. diff --git a/docs/enterprise_ecr_v1.drawio 1.png b/docs/enterprise_ecr_v1.drawio 1.png new file mode 100644 index 0000000000000000000000000000000000000000..460d3dfcfb34e47f6b31ea7381538dca6d354dd9 GIT binary patch literal 86062 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
?xF&*5CE$2+Xjis5YsNaxbxgzKq52X_ zl(zjN0qr(5K1x4j*EDOZDC9t@V9@=Xvh4xbIOfhP}fRE1GJ2de6*J|`rA&dt;*KwSK(=Yh`Mfzg0^P_bJ( z!n(ePoIf&5sJ}d|mhz$hh;0G2FCP|5n>+6u>k=2ZmD>fiDMzJw1hSzP>m@za)}84K zw`Mlg<_}UGy1;vDjEYdbbNic6M=ia1M<7*P>!X&Uj&eR8K@>N1au?%)X0iORrjzV> zJfnh6tw8LGZNN3*OW}J(LmEoQg;x37)1D94fEAvF4iSa_$}@QOteUsP$%Uw<8ttEU z&r^#NQAXUe7uiv+My->mYNmo%$;~6teJR0&V?3tb=l7gx!E#bm5-p*kqibG)$XK!2 za4a_fxm2$7IL0`}GjH>@xBEvjTaGmq;&w@%gi_^VsucW-K=RM(@^Qt;-ZxG59HZI& z^NW>dcgD^eJ1{#Y3Oi<3?Tz?rcW;`g;r*Q5U(lh?U8(TSrFpG2k$L;FnHglaSWim( zP}_J{lDZtW^HIgT!0k}d>P>HV!&cwAlF|j`+vZ#RzR*^p^&?&C*=_JzV$PAFoKwUd zdr0zhWzR(vBPJ!hKyuEe^KrY|e@Y}00LeK8pqH;FY5*HJU zJ;#e2f;bBs+DPq>K{Y2G+;gk1sotT_E#v4g+AxF=BcY>3oUPY6RdkgcJ^x*pMn+?V zDQzhErt~XRi1R^;4nQkq_^PHClEe8sERJb)b)APCbqHN9TiC52W$LTC(v_;4BG}pS zzApXzICcTWC+YtrI1m6F0BK{=#k=^^9!?gblAOxM?3?)Tj0xDTJMj(Piz^roI6*DH713~NGQFug!#%4by{le^yc=+1K%fK=Wob$~0ft|)?uKEh#pbBs%D zM6?I)g(I;2tZYmklS)P{r31{fBADr6$Vq^6SOg%OF)paRGDd;w16YAouiq93dy&z( z%_iAm;?CfIzNoUAGzYOC=5t&E#l=DTpuVCZ(h&e#*%TgRpwfwMSqHFLY{YNo_NUIY z*ezriwXu0`tWsJHSKC0%_Yd1<*-`l?A+|!x&6F)BzbXJFMm$`r=3}Oj?l^yl$&+do z?S_{fZ5+Y$o{De*oDAE#OHiY@q=~kztC?Gf!$;r0S|u!Eg1CuD9hWh`F<>jVu$^fY z5|eN@JKmsF`&wQgZX+^fFy=Z8OR?hWZv)8}JXgRT`YN6+Q)}Da&0gmy7>P+af&t7f zm3fwO>H2R=7Wh}6Kly2%nVpB#k8cR0&x7@>ecYa7Bt2Buuis`(i+}flK5MT)ud32t z?3N3~zXaElyO{7(DLaY-68;iTkO=F!zK}^vG)GzNZ9^%l!dU}e5)@z7bAWkOz?euS z#rg!H9|vMe>^kyS;C=i2WnC}mbZ+SZgfWe%De!C?5U8nTf`aRS(7~2@bb9W3;28mn z08+XogTZ@O3))Gw&98ztmjIm zV=eNIx{<&fU(`JA-`55C|BUzDIZdB1L~GhSburlwu9D7H+J6%>=edUD^mxi(ydQd0 zj;RdEDMY4T3Eb-}>cnq!8@9|RRi`~TvJs;)VI#{I$kr;#q2d@=HPK7zli7zty6%u< zXJ1y(N4zi~?#!oG_e$AfM}HZGtO#}SSk8VEhaaNv(5)7WW_R2OJHo9K(*k zp!)zuoWC!W$nfx%Q-K<($V}f4dE{V5y|W*RTKC^&nCE;kd3{bOR}<`DKV`e<(fe$A zYsQq?y}IsJLgTNP@`4mpXf&Qpawj^rYZk@>594DP6DEm0d8$B!vS+HbeflLHJfrsFlO)FDhhn}5o`67TbQL3UO-6q8p4vhian(iT9jmp4^}8}p_YW2nxz@tQ zx;*TM6|A<m`lIFCc^jMV=l0I zpB-EyroXRmm{>m1NfJy2NP^+D`I+i>?#RYYBCMoA%{z%$S#Qjk;)O-ATQZk*kpI)Y zBxOzi^J|?*G*_FFL%Iqfi}LP!!7f?Ghk(hRa1A(HMn}Q7DZh4wxU`IY^C`&DKDz7;d55| zAMPi7-H6Go7Fek9oDfGhwiFxb1IM)Y=_ZRNo3bMK4_ zoON;C^Mf-iq`GkjGKQiAfyP!UeZl<(;JV~>`_I(f|LQpvBVN%R;zvyFk4A}$m!``I z&a`H(3fIZ}nZduFEZ?*#x%J>i4Z0Pz+sWzVT6z++GyO42tV z60^Li`cyK0S2=y>b#=+N*qTU6H9?Kd$L${kgP5rmhCF#-6{frC0#kkrPH**;v7@N( zsWT`myQ)sLeF8WgYqy4g=Q?i{nj4m>X_o%%hZ=-cJx36-Fm=dFd9x0?1kbx@$Y~%< z`2691rX`dOlBwxR6%d~;Qd(E9#0EhxDU>sdRTPBMd2Y1pg9jK=6a;-vaNTqhpYm_Y zD(09gF3=Q?X+V;BZQ6KMSm%<)Vl(c24Wy)p{Unp89jD}Gfg8#>T&Nw3;WDM>P!DUZ zr3!E>6x?;q~qRA55jek&r5^Nw?V5SGR2%y&xT z6{rfQdex6?in*$lfwd{vKbxr_csb~g&coP@`O?pR z`a=a)!p}oHo@52k!-Qzz?*#`txYSirDAXXkjIJl#$sYl~%!s-f_G&Z+ z3cs`rk|h_HKiJ&>!A~R{fOSx1bFYNB3&cNN$}0^^)umQTP1cOfScXg)Bb}r5Eh0fa`wF{n-60c%uOnsOu)L^=LlBsfd!<3o(v zlY;wS3u6kqY)-7YfTvg;tc6V7;%>+B^a_7z(yPhWQqpIPhW*PrPfP$$`g`d`rVEvX zHG&r!GNmqm3toPEejXV46*1l_I)yKKNyWDXn@wx;G|v7@ll`y(bqt3+hWXT|ruskX z*b@!GAFqBgk^IN=_@4}kLuODLU?VE!{-5#)?qL3S+g#Q6U&sCHxBs0|;=hE&`7it6 z{`ZpnR}}nL6kz>V6kz}VKoqphlgn*ALc~ALbjXa8Lld$P_d7z-x_vLQPgb9PQRCzmikztU!VulCfIY3hZJyWvX-*{xLHuvyZQKE&N8i7m>t1Z-nt!coMliEYSHg1z ziMllSAd$t*R|@=`64Y_BJ^nYE1reUAxZVAoxlB~RP|*M_D=rZpo$GYYmnEtd0tzRw zi>zRKiQE{I^kbaq^?#U~<(!GdZNq|Y+CNQ#oVT3ro9Xo8>AGwduYNkeeS2G@*Zsv= zFr^BZGDGp-(YJRvGeeL##<)fL2wcnA>A}}B?B#H3Oe)Y204!Q?BK`7Di}v$2fu zs)WVc?pTGsaH;_A zKM$N3KGsJp?#dYdysJ@v?46%}k@(MoPi~=N8|u+cv-zu;dPn9BZV! zJmVI3r>MC|gHRfZ?yZvST<0iA;9-Z`mk=ldL67}9#ucy5xRHyhgI_+5EomGcc8@g$ z<(_NK(WR2AFgDU*&R*@>65IX6QXLfqEAA*EM6umoyM{|POAe?+H%Acr4|qcfapH4n ztCm||5!D^+QOqy7@E)-vVRD?ZN<#dbh7bJ^74{}niL8*$YJ532)Q6&>z9%~=#*VxY zMB?fX1$k!3!pzI)LMCqsMbH-G!@t^M#8Q0*!Kn;(6~m?7x1!Z=K0$pA#T_iEIBHd% z9BmRo+xD6?`W99W$2`Ah6gUme4HeAfGpbIduzlT4Ya=xj=M(T)uo!95Mb35*R|)Iw zDE?d>^dGIJ(|bCd*>LeOXS}n#%Wg_k_3>`y^4NPg~de;c#q!^!FsLpn%ux&FL ziz(Rbu+dS>)Rl1zv{|5Y4{pXOa);R}sJc3RH>URORDhIQ!HGyVX+R<*6$#gF$Ga~_ zF`HvA>Gz(wzz)&i!08`xfOi(Rr{IjK-TegqQGxvfiUXjQ#q&{BACYASkA&RY`ik{Y z#HizZfs0SCI6&KoSx~~lmit>){^tgiD^s!R?ZxdSL)!)mS)2Qtg zAKWyc@UAI+VgPQ~2g@pFI?KnEj0UDA|akVv^rTH)>Nffy4I@)D4|Mbh&aY2TDF!HBRa#c$tx%f&oBmLHn zYuSNC)_eP6u3QBmPE9*rIzMkFBPpv9KDUUh)pqC5H?lXeGK}@H~`L}tDNp_=M^8oo_%WR;D zF1@%NxZ0a8=IWVV4PsjxUMvvy1z}7Y?jZ+o7E$F72mX4JCCs*%1Zc@1DnCpMi>IHY z9J8;M=Z)vBW|>cEu*I*hj4U0Nc7xIrfJkv3rRbdThP@onMp^pvwocy8JKJH&8GrDU zo@vrdOLA%320UJGy4Bq`INS@GHfDk>L@<3V>Q6#XPBw-I@R@^D=gft&U6AkK_b8m% z57db<#RDLG{pG=8tGBQtQ_XkLbF=SQ+xUCi&|X{P25(KUk0?e z_GG0Mpzz%<7tVR9a{mjaYlv)unCPGfy0wp| zfAc00YJTW!!S0u865?JxFHsQ8zLQnmd;_v@ODOYCZMB<*gKih6T|DlBz9H1dX$i19KTEpgb-tNtRcxeiR$3R-MU2zq zXU{^C1p01u?pVi_m{paq95a;gDikW5lPrbeI8yC)}#U~`BmXBLmJ^^ zs^yY^cZged#n;sZ5LNN_l4D^y4_ImP z^f>|lcyT6o;`LzSd)QhTnH)x)WKAG@UzAqfEGbe&=%>Yj-y71|jlFRBJFKNxowsOd z?LRq9i-I!8-1a?3{i0{zUvN}vAz_}`^Pof?-muxd;P@75B@Su=5!)EloIbqN{@I}e zbUEMi{KqbJN&eo19^1ny`bWt!*q3a5J~r`s=KS1k^P;Pnfspr+(gMEJv-(yBFQR|G zvErh!)t7|aMHhQ6&kkm84?ulilmfh@TzKcq$2JuG!6?3kxbG}Jv!{Pe1e6HHVW||i zVMBMw1O$(`r=-lO;PELW-q9O7%so)OVGG8GTK$l$BV>suQ_azi!870EFCWg}9iZ{E z%ji&KpeAizOHywyGjLTguzLc%@0C-w-ekM@wZ12#^dO8Ob6qi_s>+YJ8f43Uh(~dd zpcZjj@HL5AJovR1Y4JTOT2E4MKg2}blhV7}&aMJArytX>AVGBvK?*sj}6UX$WF9WHpP{-DqOrI>cfy#Q9Gt=b0Oc+{YPWor8Qwy`DNQ zH>LMLNIm|%=+m8ikWuajg}bJ1HM@2beo%7gO@^;LcS(JG+iC$*mRSfA{HugrL45f6 zck2B}pcGneUKYrB{q2w}*?Kw57dq6nf^?*SZ|WuRcZ`=Yh8D)}*rX?|uaRC+eY-F~ z!41H6)~99B=yyO3ibbOr3g{oSfp@D!Hmgiu&|b#KW^QR4n9EMbKmGtig0R_9RV}HW zE9l^Z(C5^$DR)#gOMSKkItmbBu$KkiJIr^b_n~7OiY?){;y}tNcTj-he3UC~A$V%k zzkeCji;nBZmHhbX3RSEYm=O4>!>b@X_1^O5WN*b*LDpr)P1EZT#I2TnDjF|1jLm>_LZjOf z)`Z26);@v~J0S?7aIT(O<(rN}E59=Q{OB?e)ZQPOnEx0b!2~;F{D9CV0{BtqKW$J` zW;{R?YcKW!;XC(q^~gaowCrk+iwJv)2vvHmD1$H?!SY*m>d&lH3x z&6>&&t5I5KsD5coX||>r%{<5-D(86~4!Y%hvfil(ShaN7@C0JsgRUqpxkmiLO(R57 z+>t*vh~SHtC0i?Z&YnM$wLMN-G3#IqiinzE>K!vJKp?1>>SF<$#65upvaoXWY4dL+ z*pWy*(S(|3ZJ;@0W?oxIhnu_PN0!B19T&TzD#VU;w9e0sezxvNjFnV+=JRrw8R?J? z+TUhGDB0|2Id1PIP;1o=w0XV!Jjj?HMCZN}Q72RmWxVQ)CAtwFeq!!gX!}BSK0#}N z@8b=up);mscz>)R2F_8h#!$U(*$CxfqYh12gt_2I2*3oR#03zvnL|Seoq_RziOicD z9=uXZgWQhzofHa?+i}EPEA82Bq;K4h!?0wMBI&49=Tfl{ zp&zbB>K5}6_i+ft?aeV+tSJ3(oUwBDH&){&RHh zeep#z7eQKri`&j>3A z)fz9rzHmtt39Q@#tmb3RoO4PHPL1O-RrwU+lodS3gSK-;T#Y>`;60GlRLRA05gKwH zI3Hx|FL;h)hlY__LUW(PtE+Ah2Po&8^=*~h9tdvii2xjY$4DPrw}^cUcyP0$X`q)K z83F1i;Xfbc5|u|WP}wi1%{wOqk-Kt2hZ~&%zNY0D;OU+jJtZ^v+eVDhIQi)baLvs8 z_2ZsZDLuTxrGX+sC2=QZp#^rRzo>W~bc;@F80gARs+=YfT0~hKZxn@60wUADERH_H zhkjQFH9C%M;*Kz?FXhHvTAHeOs(hBb+z^o&V!aH!z!VXQAUzaGm_| zDh}$R1up((+dY+Mpb(<(1C1-g4`Q5L z_o0QnCSLb4(1?rxJbt37^nhW+@kqEsj;Jg zS>2crtxX%7-joX-M-SrlE4asPWxddMRfk6oZ#8wbVvmm{7$53^20PpJ)k4jYL-R;p zOGNia4pN_Kyq$`-0zm7)jtvM;g@=R|-VV=zsxFo8)5>XxQrJR(MSt)aH)DV`P|fQn zjj@b@S^ohod!Lt5dCmlfn2MXAUM>dS8gAkc|GEp`V8&xCUbb)gAtEVOpoY(}s5L?l znVO>?VO%X>MKI5;yI&iI^>v)3c*}Xh|^rC_&`*0ea|IyA+*rey;0Do1uJcvj#=KBqdy`^a2v+SKaa9%(4`u=3RWqH zY!L!U$~G1O*2xS()}o*c_Xf(1{3gMx&(9UcpSae&eR=v^w($+fj!@?xx6Fn?i?J$T zFwtana11Y6tH2Aw#cjSBi}VV{M*>w6?-pmZL=84~5jQ9bmE2|Q8H_>aO?x~W+z-H2BFfy@S?@RwEk|R8e{4G1 zxP>7q6VZ8^mUUkj6G?b*JVenge}yrstMoyt zxcL1LI$<_8GEd}~JH@6-&OKq*%^|g9lJc`?LZVbb|KeemI9P@R9h!Vx|c3~NRB~q$a;GONgm_s<43!*@0 z+I{zI@TH3v+o`Mxr7jF*9W^DW4D&Iqzd3&no51(NsOy=vH#*qAmg|j$>mlPEpfOUy zm2%FReVs!Y*hv&n`S->_QJ2VN@$vyhs*?rGA4DD=U(PlT#bMV;egEi#$8%|~^nt`2 zGsDfI-FBhuiCudZ<6)g4Buyxxe|SLT*E%s)&&3ek|Y!!(!!^>l)6$bethWtg=)D4LC9N2 zYsbk)#K}#3uii6brPGI?RN9jf#Fluh7{kg=&Q4~yyS3%?=%n3nAT7-0LE#23bjeX! z$_fxq8YYkL0`q`jVY&I%M0p$2AaU!4@IHZP#;CnvP!%v-W>)w zXC9Kich}12ok`Y!#~E!BroprP>#I zCI-7I5R)ZS%L+ncG$Mqu^IN({vPj(9qEmy-*=9b^Jd8!7^2gH-^VD{_dO5LMGq5ge zUgc9PXtkY5*NBi%$tPxcNA4PVQ7hz;M5P@L#D)PbT=99942KM}SFn=nfmo!7*VkHw zTp33r0q|>_gE_6-R8#!k=;12v@Qy+JIn#BB3;2?h9K-l6_nXO;P7mB$VwnK!LPU3P ziNwc<43%Yidtuaz{e{e@wr}w_yj`X_6x?2VQ=D*$gTdAIzqj1h56qhL4EjU+g7n!n zjwq$+EeIJ91!o|!_ZZ|)eh}2z@lor~sgQYrQ>jb1%{2L;@(bRFsS@Jl$WDdksO`2{ z#&p7iqx##fD+5u<&J%WzL=~9vv5~)4Yhyv>&iGrhcuRPLNjc7nlevtAf48?TzN467 zizgl(6wGyDXLnSf?~7sapqH^Yb@nq;a6s=*7;lm2&k{zpz!LU)99fNb9xlu@Ex!~= z>CsS2?kbD1TqexgTT^1y`Ig0((F55IHUrY3Cir9kJ1y7IPA4`R@6T`T znJcR;+unSu7QrQ<8{*FOy#2HTP5D-nk}GX5)meKY_C{<*vH1Y>o!z4MAZ+fwqLA0^ zUQ7LFfS9yCH#y~aczN$$^q0_NHd3cKWj~3^PFyk+WQp!gkc5Pi5c0_Gt1_1({5`9x zMj++Q*I|+OG9~d4hYzcpczNkE74K{RoBL2#HsmJ@BgAO zL)aZ$muOIc$1)&W@T#)ON@l8bDARZ(>BIWKnqi}W$xN|Px*HP~HpYTS7MivdxAM)M<5}`Tv_qCK@82)t&wl9D3 zI^`Y)GC|BOIL~?YbhEZEP6o0(`{$EWE~O#)HSp^B6E5&TsNcT$=h6curXR_Fs=_47 zPQ)P93cu9xpL1cb20IU?)x2}ceWSQ11N}Vr=ab4J@X2QO!mTU61|Fq7q0X+!SA&~> zwoY)PvYNvJ=l9e;E)*Ck!ZB>|=IE4M-V%d=t!V}G|J;*G!jpl%Uiu?wylnt+7PNZx zg?14=z zdc;`RBY-$PMLE^BzXtZUAvjSIakYU-f3^;!11Tbl@N{Z$t-)nQxa8j6`+dS-I6EeA zT?T)2+&*0pxV=Ez)R~+fF&0h*AWoKzPQcjjfk((rWUOEi<^8|Z!5Bmu6sJ?y{8ET( zx`rEnZ}qqo5G&u3QVdTQB!4o{o7Pj&_s2>hss2511>*^~+fcFl|K;{4fW7jVPpNJj zTM4jaC%@Lyg@1pE-we7FT>?~ zVBxUd!&>8zywb||dp^SJwyUFeS)YFNy~w64-6k|~uCKr%>OGf^ChYjoS@`*E*y2#B z8WA;DyhKo$$i?v(XU~_$r<<0j1j@mX@$`(yNO3MVndS?e<^t#o*iTCDg7T6#Pf}lC zy8SYXx^09p-uJIDl-ApN?J_M>q|bMH3h58P!XnCAwSO<{HB+L2M!I6khP52eh0`CBy?Tu`t|9x=6!-U)mAHt@w{bdT4uv1<_5ZLcZ) zW)GKWZ^x}m&<~7oSC<%r%YRoPi?#Nq`_J8l5SniEfxdZ6pr~Ua3vny)H6&{Pyh{=O;%Btb@$nGQn$ogQZRh zA;Dk=RKkV&*tfqKG3k%GA(~|8m{Iwha3fk{oJJ4vfG5;p=Wyq?M!D7NE5c4stdSdx ztnolW<-ns+l{$srgWCtGOHJA*7j-%la>Szh?1viFBEML-30ip5Vl0?4rkX z?C++qGd)z-_~7` z+SoX{$n%ZFObRg*0$=SD4Y6nf8f=Vz3hs_8e&c29ighUuZq$s_jthXs}7sE<`O za(_;&QWWPEbondP=ww)F9h_>a=aEtcnno(UlaJYOVoP@0GlV-z*S>w8_H&`4WVU|s z$D~;%mw-5giZY#uXo>j?G(_x7;~zCFZRYZ2Xg^UKCcmyxJN)KM47>0mt)L*wbmJ%q^E)ANd+ZddUY;9Mf% zxbzd5=M5$J?6S2Iw4B#>UsTSktMg61?~B9jk=)~#F4HkX{)~S%$Pfxxa-AS-`q#hs z&=45ChGru)V<8W;t{G^?F1ZhHGbJ3u_$k&n{5|hdoX*EE`Up@4{+w9qF6QJV-cdYR zThya2xT7IL+}*SzrY?de4BbY;@YXmQw{La+@eV+}KRhK25yN(JDlYyKkuFXFt?(cD zauuZV6C2c_$J?8kVBkJ08k|1{#JV()Y@t|Yzcv3WAMZeDueM7Z>AaL%c}|Mp(*A0k z#w+OUMdH}M;z{9x1O%O|b?X;Hy^9Ak^{m%$bY55Dk#jTXsojRntc?lg0%5gFXX18B zkYqBzhZpSyl>AN(5=92KHBYQb=E^+$=1MrEzhHGh`2V^*%%;$Wv>wr5IO7K3NhysR2!p|;F-MfO!yBtc+ZuGex#A_UmL#USDvXx9) z08qPe`swtU6QaNv!fwF%QHJ)90vE zHE`JAI<7FKu1uG7HLmUb#-<{2RQwRn#@RoF9%KT(4V}Bxi8%1-x`CO6@D(&B=9-z= zwIsdlAAG~x)CmfzZGiiRmRkSM%S#;Bc&XV-;W};at6sKlLY?bIz1BiXOHO;bA#Vvj zz<3{%YD9li9*UuWYj&L!1aYlx^1)lV3RGYvnm4pIlL~ltrN*=8|EHVL+_qnoi{()? z?|!Mz{o}cqt%D?6m^o?1xloCmj!>&jx>OpUFH9a-m`pi9O-o zUq=n@D>`207Qx9p@4PW4LNc%i6u;SyeL*x{K;;Ch^*qzw8~SG6Nw}7UjMvzcWxvHS zpUdP1VW-T5-zakacDr}WO1#acZ`(cL;c0q{EVQcD?*vmTIM1YQyv3Q@o!Xq4X^LEdy@NA}G`%BL zYnWIHxFnNRNMBYgol4@>SJso$`@w$UOzX?#(nMXk&M4i`Awgx5BR6${+<|Kf^2=7b zvH)qTL0-;JsIgFmwd!u5PYj}vos-jcPQ9cHsR5F zSCFT|D=6A{^!+gQn(Rt(ks7<}#xP@tqba^{nkr?dDmP`b)K)YDC2BWr_t-g8ps|vK zY3l1E(McPXrnt4H_uQ;k@e7F$ko65AcRlih`73&B5ylo`4w*#3us zQCw8FDvwHtG;CyJxE18*jB5~mC{#EnZBb*n=t>y&lKZ7S94Fl;2HWedK6FPkiUT4NPErsF%7!~t+O9{pf zEe4GfQl>vhCd&s)S(osS|70_g^BBKzi5L1T%%!mXm3g@FXxA{a{o-+I8IywSoa;S^ zyH=s~!K0E;mnRz)aOZRH4IhRy?mAlFE???K3#Y4Z+H|b@r1I?V78&=yQhRB6Q>7yL z+^&L`YwC(o@ooie@~}7;q1%X9g-#dxTFsP&_&o^vqv4moO05QCJX4wH`+zGKrir_w zLmr0&IC`w^+spjH)spb;oZ(wP>{5*$#|k%zE!d;?Io{6WUD`3=X4Pe5Uzc6lg>{qq z^dhy29}UNsNYHsDm6D^RHe-#lRs_oKhaEaFXMQe}D(^0=VlTAt%5~?bS!nv5*=Rw?Wayb0u|ATaXl&`?5rgl*Mo`Gd+f)h- zFGGtWN{+utPs_p{MtU6t=g;-ugS*@NLv{@m`o7tRpIhL$>tDVO#FRs7@$rEhf3ilL z#Z(MTX|ge0G}$GcSF)D(gIds*V8g6#c#1*yddIj=YM$MciR*k4bh7<*sB|})y?GXn zYF@T-Pe$=xHJ)Xnn4ESBPRV%<*$+b1sfai5dZtCM1x5YZ6xmR7kUGhLkS7L>5u5wq*jct!)1TRwv8cx}h&P_c%0rs%xrA72&Q z8N+#3m)~FlD3uD}j*OKRDMLh#2W1c>H7Mqe!0p3E=#)P<87h86VB@!)4putISc!kl z`5W(vX(djc*q@3XR$R;KDR#se*O=sOz4pPcZoy|h`7X4^^<{I$`DUQ~|Ca%P94B#> zIx&5Gx|o3yZ*|Dac(ljO+P?BAVy(z)(^-!Zp0Y&+-8!|Gu2TR(YP8PmfVt6F*hsR5 z3n;GjpyHn~GB_3$`uqq z&f6L3+pt|R^L4A#=6_n=C=1R(j_t4(8(c+v#v|kox{lm9WM6;Cnf-tN)xW4R>g3q6yU>o}S!7h5}#>s;(_Q?rXT8 z*ouX$bPN(zSFo@m@J^)yT-T{yc6mj+(D9K)vcoIN zV;61gC=X9XqWP?jM4UFFrR(N8lEx;Ua$c!He7QfOneImhbK32sUA^M2*5Cs{vK>o-9_NkOa8XrB#uz!|)p3w3%4h z!?`}_!wy))JxLV_v|e(=$hGQmvy~)0-ed`r_Rpw0#L}NGo|8`HY}Gzh=+aUc2WnPj z8pODgulYP#lf495h2HBguwWsk;s^uSqtUr;JI5d|?E2-1)O)=>*;;a4(Sg>WzFy$P z0HvBXBfy${`{vEL7y#t_SZz%z-Fa>rP^uN3z||D zHGFfi4N*&ot=ioL%G&EY?_~Z#T9a8?g1Ijrm(7J804y*SIuhDU|1h+87eFYufunSWu-7;>VUT|vcr-!}O*(YiKIug2HIp4*1dt@%{am+YgN?jkcDW$tv zI%fQGPjkc@T&LwhR*<f7F-Pew8Tp zVz|QBM^^@rx+EUrN<6TGT=3uWM+XznI>>0m6_S-!$%QN61FUJ3ksh@fGJ6`wk=MLz zICle8(3>8&#CUuFhITUm&X&Z(K3w%2t;DuXA@I2-8A!7>1%Qsz@~ww7GgJ%{G8aCP zqm&txo-U4le|Z-gra^A*Fx~PNAbBg4IImcLY_-3W$&r>XCvyc61RW@{5riVh9i7(w zyRYG}7jZ@ulvcbu4A^dT(uKp1(i{BzJ5-#Atf4m%Ww zj!9|cxdn7(Xv(+cJkfqk#eQ?QO{jH3H7&=r9=3mfYf+p-+;V^=Q(!r4Zzdv~N=;2p zhvCs3G)OVmq2kuHyf+Jar9sl4B)zzJ^9jQv=)$qtRbl%Fg;oR1AT?RQtJdmAqR${m z20lul;U&2CWgp#^=XJ=(s=8*vs=Pf4UsUG04FcD{i36U zihr;@31am*m)Opw)tTGu7%B70;hUyOQv>W6*Yt(6h(5f5}Q zxev1foMU^?A@t2vksi-#?LvnBe7T}pUUo?(zXCDOy#^IE9b*rT&rcYm2zemDJi%BO z+gBbQZvMC(1FBaLcaDb!!=-oq@=+Ci97wu`u&vg%@Q;4$t|)1aCQ58i zf_Of&ckfx1>JDy@eCJTxf!HC4%-on8a&$_Q?+1{0yh8h`t((-)Um7qT*cWWNG)I~8 zJXoH<#I<_vu?1y^Q|?u6q_JfLQE$bKw3I04T9UJlA>LA1gP`@P{n74B^XgdjuExR@ z&5^BS)Dz%&zXJ`{nrLmx^xJwKceAIxz*aR+B~o!qU%kR=)yc*~CLe}C2j5ti?G(_; zH`Tv3kbey105FT@KN^Eph~qI2sjFV8RlHv}ZhK!+z~*HLk&&VH&m z<;RWCFIzG}IJ13*Zhf`9!RvW!hW_j{tIgcV27p*((O;{0>ltVQEp>%BsxTcVP35z9 zm)r;k_qkvuVATm#1s7Pzbq_l4kQVQCI2bIwaH3=SvKq9K?DD-+dTb+F&)zU3)tpYu zL&#Rh!n)r+SCDX4zZA3pz3$f;xBR+^O|BaPvn_oug0xZIb_m}lTvQi+AkV1{zbL;_ z%J$JOHY2@zmrpK~7-x*Y^m1?rnvdTR>`c3>tSJRICCCuH$^GHZ-;K1}`HG0Om?6BemLcXi;8C2%qH2 zO%TILdF34!^2*MVljO@(_MP=@i(zIJUMYWF%T(6*5wD-hY(wATui@xEe?lT)X6FqG zEt(=ZwWPZ@l8!GJ=cU@3myChb{hQawn4W{E!T0uaIIbY%5sB}zW_srs(V90?X=i3@ zH|6qNA%W|H`a!n|tHz|VnZ0m@WBd8r=S6`&MXPO0x5m|X!KH?8Bvy1IVG~*_dpF-1 zi|5iX#2~FBI{5GGqg*)JA}f~*Ca!0jO0ufBlO=mdJ*)J_PTku8t*<>ygr}KfB~Wlt z$xMCH%Qa#OeC~C?u(kgxnsP>&o!ZCTj?(tf%*~gl(s;_d(ax8O_Yh-o?aR3eB0Lz+qJY z9;Km7V*QSSbl*m_LOf6Xo!`(()$9*`QQSc{=scwf`SuB}Ty ztCo?RTOn6}H; za+HD8jQRZb0TWYT894xw{E_SPVd%f9*B^!$#dmGJ)m3PiNjOkg_WTleFwxJfzu&V}d{sPBpct;s zbs4M(Co;eq1c1YM$Da|6Yg|cWPHZ*`glMfTX_~oo9=@}iG$ktzq-<(>x6A#gnCC|8 zLN&8&l$e4z?Khyx+dDS&&bMw`(YtD!w7^(Cd%F1?irLlW#0%g!fOfIrc7QzxkMP+s=*mtvW+iM z5LjDGb$4%w;|_Uq^Le_hz*B98pDN;}8!>F=k3kcS-HtfWps_^$HLl6{%07 zXxROTQtKNj*5;_zIK;FkhAi@4Gg=2hC+b6^fG+fRj3a_#+L=qpihvhgKC_Momj$gY zaY2OEx@3;o6?E-5V-R$IlTU#VdlVqgG}3T2SK+Q5D_C; zVJ!O)j(x8__8C3p`d80*)8yX2RoLWxKzva;DryFHy?~2A506tB(k$d5-Ctx)^$N1@ z+Dl^Q>UpNG!YcE9?vvY=lUliL+YMXvMbTdcJ&}xL-6li1PQF`X$yhYa9d{u?ezE&j zAcV1f7s4q431S)A*<5ju5EU#y1O${6kXBL}rKOY} zQmJ7;LOP^Wx|<;eK^R)VA*4}6ks4qKX+=W1L1N%t8@;}9KhOQXf57|8^|?L>d#}CX zTxT4|aZ+IK2l9t6j2=70Mx+YjLd;2}6Z0 zba9!5NG?3!^6So&Hl^YKU01${>+SoG>CuI;CSFZDB|iFiaJ{N?2dHqVEeJVGNU%h~?k6{*FV1ym zaCN1LBr7rNp*6z0Kg(FO#WqnDmYFK=0PD5(gQ+G=cGjjxdB?JBJQ^-FdCx z0c37ayYU`_+X1=+0iCFc0>Z@ehF+H#M0mJ=EPcZ4U!pxjg78}Xe91Pq%ZKz_pRl6D zxJDt$P=q)z3&w*s^q<3V5N5n?NlyNx5EU`sh(vP=GEvPYL(@iIRf5qCQ`L10N-cJOM z#}|n?_VrG&3p_@G$*dl&%&0_OL#d@0IIT$5m(IwL@wnlpLvw=kK^^+5z zC>;vtlM)egv_dAj)hunw6J(1_c!W zC0D+H zw+eWB<@=}}z$|-1;IZ8jTD{AFmJ|aT>Ip3&;bNIQhE?e|xoay&>dQ>VQoZXx=Z;v_ zxApN6$pMp9b-tbvH5|xScMBc7Vfe^sI20aCdPDHs_K=;U4p_B0Q~lA3>h9Z^r@#8( zuP-hQ!L%iCMaD&R7HcUSnrPLU_!U3Pk(@I5vtw=|h%|d|#;SGvP1OA9&Awa}%eC(x z;!voA1uvkjnH^A$f_AFECbE35*`LzoJXO$WF?| zU4_EnC9&x!3Oxlg20DlJ|NOwg)SOB!(`*x zL(s0?jJa=XVW>0{f;RysvE(Km^j3kJT!_4lJ8)l};5i8g8Kftk`|E>HrXDmULT5~v zf=uT2YVI_Jh;wG+W^v)qpdVU zU5rUOyGEtj9I}svh#NXth8G~uDWqi<)PpYy-W%W3kvLfY!XRH{ji7vo=@#Q+OmUs> zYdtjOqx{mizreMrbLMtKaYYw!@k}`N-ahTtC=a*cL=`ZKShSJV05#Urcuscw1)peo z$%q&P%Q1m`TUe$xBN#Qu7j)L>*nncxTnIe2j@cIZy#%XdmRENkzM{J6T%cV zrMlm(&!@a<#zq{F1CTMZcifp#o}EmW(?I(9b`O#39DIGLW)5{BJEtIlMIqvLuO&F# z31=_Srr$)lE)J@_1#n0jcMIey0=L`K<m*U6t!r@b1Dbw4Q41~;0!4ZINMGaM5mmq7Sa}<@WM;qGafFo7Q3Tha!{tn5Lp$* zJ_R!=sKZTkOd+rI65n2Y%I|&e6lHy}0Cwvl|Kge-mz{v-G}3hzxnq~{1btj>G9-Zg zD32NkS%Ls>L4!yE>=>-HfWHtoHT>6c()#N))`dN?t7(vxhHcGW$R4;`qQYgQpSAnZR4GZwJB#}1Yg}S6uPa%IQQS@aQ zGK^K$&H~_p#nItjwhsSzeSZ?*i5r8S_BTP!?8x@G%8tum9_I@i5H1<|>w8ldwWAw0 z;1$j`qg5sS#V{?e-IW_vp$+fy8^quhcyZ56!^PIGq8=rDDPCPH-{Mt?LL@d*M4VYr z1&)y0w6QT3oilhQS?Ti+*}g_s0fa}F>z!~@lPlPMp_VUd7d)&te*bv)t7X?>qti3a zq-Xpbi_m$n_0!l%XMde`KiFAT8)$P(9s&u5>x=yb@lQvq)b4W`1r_(AD=5hjcMTx&~zKOr+x)T?{0`dsV-r-4IJ>DiObQ8*idJ_kxi?MV_aDyWFO=+IHrz(=W)J z#+oka;@%-6PFYKJ=jEJEdyhaMFcBe}={n?l9vpe0?MMT1MxHw{-2{?`rX9zGQt&##_=-Lu<|V}8u2}y`M#seHM<||KL=&H zFUPo**vEV@M_*gNqv@CB+*32rzrp)A0$Efxhgau-E%Yr&{7F<8B$%BHTC*elvY1oB z9&pgyj@I!7t`)v4H$hf9MqXuNaSEn>(1%#>43kI`LWGPBW|bN}+GVB@*rWV<*GXGj z$pG^tK6JlOKdYD*gyYpu0j=p8%=g|e*a53QQ=y3YvZu4iOeF8m_6M{YM#?P{9a zWEol(%ZzooX!(T1V?FGftVFmQyZ540^(Qi}ji-O}=U@M3`|tQ!KV(95r3xu%zdJ5x z5^V3F56s02*$#4pV~Aieta?g9tiQ8+pQU9BUO_e8TR6C{5y-blN|z;Fq;oQw-Icxy zgcb>V!tiQ=R$df&Em}Q;_G+)y&T42Qr%qu)r5}qN=&aTL@ygm*)Hi3_1`pez$CrR7 zNqyo;YFA7lS*6rG<}a}vzN*vyeV!e)y(E2CNl-IOnNMxELJr0t4jRipt&4=Pc zSmJaj6E^jDG1qJ)u9X4V|A;ctU~==}!>u%9B8*}?!jQ7D!h!PL{ZdEZE^aKXWxZ6W z_j=lP7iY2xC}mXUSoEsMwI}Ms+It5z1co3^1RC7b9rnrq$@{b=<2HQhTX|oTpWo&d z^<&K%W=4TXi=gD^IM3-=-JRpzm2bLBj~>r-B*g8jtt73#^!_@KJaosd_-N3tiIt4U zO5VQUv1RBZPWAa*pF;h??5{!!*Kk}$)37@Gml4gn?;qBhKYBczYX^cev28kfva1;e z6d`c+Sko8h24lg ze*PJ;Zbb@ZP40_CR)u-20mcv1s{FoL_htv~c|P57NNK}>*`f(hJGP$FzN+trNCVED z2usYk0bl4iWduOp-Mj#q1y6nva7aF?ffc_I01m5N=_KjWD9ozU({$g}mO+X1QY0~E zzbqTW9ncZ>y|1mb&$8nj(ObtU)Au06=(SAZ(fyPvJpi2#V z&kqJmM!NKtV&(h-j8N|PE1vCVp9 z?MV=y;X&m^pEhyO3+DokH=#u6NG)s7t1!4OXLgubl1wi7h_b3lD`fG zyVa|n7m>`RjC*S5V33+=qdWxvhAPtKW%{U-sgTF&ZNcBnVghH`VtQ- zzWT?j8hazH65b04bwaCO8+~n<_3^hm-wIo$;k(Ug}q&nl6JT-uZNGi9_VbGk5M|1%3W;(!QFkaosI`* zbb5K}1UOi7?Fy}_X-Sf)OJ}riH}g&fqH|^~$Mi=Qyn0pMWF}^q07ar&&gF*%ex3u+j974xQ> z!-lJ0*ZX_{8WE(>I(%@M63-k8-|5$jl)&V@S1_R3aqinf>3_n&>x4I;sbzim&O*8O z<>odsXjw4$YLW%Z?EstGeWfzm?_Jz>79W${Ywg7rmH5`28e4pog|GO<(vD?43)blh zcBJAxQ%q_>tZ7ZC1SXTlYVJB`)V#MF6W7?mj$pe|E5Uu7wDX3Y`V_Lk$C?%nI>;VK zO~ER1>RmI_riNQcrJr`Q{S1rr*PZhP3O#1F*Uh=A2UQ|w_p@nY;f;P!bD;;?++Aix-6|2k4j4bLof?E4PnY_E-s= zXg$AOoN`@1rmc9hzZf&pf0oM*H}%GjEyAl^t|$;hx2q1HaQK{s8lg_4W4h;T`K6yR zqJzT^KoUb^sN(!N$62K8YsnF{cOmekyH?R=Js1z|TXmpUmK;~s2rj9f7c~QHuFovY zzEyxS_H2~z2e1;}vq-d6;ltckB6I{T<50!(p7eODjAv-W&%7b7OUbUNI9I9E#6m=F zib7$PC`h!{JSghquygLuLC#9Ne;LgGf=G_N`tB4mUXWra+0abMo&_s7#VM%i{=GSX zZG(G604pe@_2#{H*#$}GK4yD9!q>f)R>!FPD#S6e1fC-go(fu{80G5B0?#oqVjDd4 z9BD1;?dqVH@>ta4n*d;igmzPBS`9gto1hD2@A0$5{fth2Mc<|E`ZB*mL#+1Q#}n0s zk8BurD%2LYtqbiGSWtmQpm?AS2Gg%j`L;qyrpR0D8dC?#%O>}!0Y~vpg}S8~AKPP{ zUr&7;6k&~9@ns;!$HRUa%;)KjptoyBs0?@n``%?g_WvS0M&c~kr&?sU&{C9KXjk}c zeasnq=Jh2SemPn}YcjnMTAw@)4zKPsRCMBbJuvwS)-=MMzcp~tN86=-p=gI+=PDfs zeiXkT060jJ>$-NiVxAvXMVD1TB~`M=G?0hu4Ca_+w>__;@v?Sfg{GKLBF6SWcUF=z z{XFHr$+I()Z(|+Lt=f*{qn#Rs5oMyss$9M!eBOZ?KI2zcepxA11cjrE*f#5Gd`?&<(=4-Wp)x_V(S}pjlo&PZF zb!MJ!I~v^|Ebd{7QxLkb4sw|SbD4-%>}&ieT1`e(;K2RMWfp6@@l@AoWoy?Sr2*lW zI}W2&_XdPzTLryG&_~bYVeegQDnYi1?Y3r2)wt1W+hBIAblqn2Qs(t ztGwg30D)UOAT z6Dda1^T0D)lWLkQJCX?2)ed@3PcNIL8%tnDAknssK|=@R)#!5!&mV3{MD9*_YjA4k zJI1{Sz!qV1ER;FtzC^c%2DCd%%v?;haV0X|nNMGc092Dq*U+$=0DsuL#GtnPyE#n}nJmYF!EnrBZ2 zBeFvUOgJH6dkVn%OU#l5cQI{rK6y>Dz}pKL;16h@S;=PvrlG?$l8AvUlqpTGvOIqS zsDD}!-JvWMd|@}=mph9G{nKfGsF>=-KJ9sZkN~6uQN3*%rmKsdf()|=a-K05coPX-J~x$cB*4&d4e1}wj=ZO=jI1V zVf%uSu$HOD>p+C2j^1-Ur7#agXAyyrv%eRnF{O##{8J z@hL%h(=wZZZW_!a$w!Hb$smbxR$}=FxThHM<)8&Zs45x1|Yc zvQ3cj;s?mD?|5;S{H>MogHn8*d2oNJscDt{cxokSX)R}==nXL!rBp$LS(JH5RfaBk z3Bc9${0==k2d=0s2?|mA0bvT|v~tZq>D8$JTB!`WDWtlZ{4H;TH}w4u8GKgqY2eC( zl|8D&p98=BxTht`-xR){ewiStI)|7E41t}ur&y2+{n1zJt?|?oE2U_bw=Yf3 z!@Sjsye9sYAhG*G@?$A0nErePK*FVf0v@9xf!eCTLAAR>`Kt;5KU2K=xu1%1W9!=4 zI*;UU1NTR)Bs}u==_Af*?Z5JeQo!c6A3)amcp{SzRErG4uJW)k)Qf1e>*e2yzC^=r z%wWw5vL8wy`*)7HpA8g;Suz*kzo>7;@bY2tN;bxhp@;Rh!4>t50Z%8ZbQVkoA6~xx zjql|b)jO*t`#UN%7*7^l@{Z)ec&lcis%W(5ZEt5X&}ikYf4O}qyu9bUWHNU}boxZJ zW#?GMqh8h0p8IEN=3C~y!9~HAnsSs*g)MHwz~Y12>~8G0Q@ZlS-HA7ijbKrfKa(v) zCydN5{f{#HX|qJinE_BiBY2{6U^`fq7LZlyu!m5TX@1v4P5UGF#kbdYv~oJ|B{?1D zZ!A7^{Or{C3JilMwGA}L+9LK#gRZFG!c1z-y-4l*-QCUay5;{mq{@*#{AMi-ud{DB zxN6Fby@Hv*^M`@VVF?%(#_FqG^*EcJ(X&8MhgH}jRp2B8`|)##{NM7dQjOCL;h#~d zr9qN1h@9%-CcBX~0C@R#ie*bbkk`02#gFs(yuQ_O5ZHfUMBeU*k&1#>6zxm9pgEhO zHd&gOtIb0>!*6)HdoGxLaJgy@9g3h>wrFd_>n4Nw#(e3U5WRt5dLGVUhM6 z8V6*Jzk;V1oC3i@1H=ydV{ z?TCXfm1>A};Zbz_N-DV?vKR`Ey$GEnq9m4F)AMSrSU+1Sh zs@fi@RN0l|!WF+k49)i4kNhpGAaxW2%T95nPgRKAUi8XT^_j_t&u-PeIr{!d$<~sz z{zzpl6Bz>i$a-+M&fT6g#9_qU4e!~Rdk@rCJcq?&?Ka~*W;H&p7({x^@*e9eMpr|M zJB7EbNVI7QsFZK_B`9+h+JYkS%We%!W}fhm+~E_=orFO2)62iSGD9!oc4s?}Z!;DL zif=vzAQJ_n3z7H36N{>F&%{C6C8R98pBg0PZ?VG-OTkUv{;zPqd++bFcb5O?`J~-` za{nQ1E?yGjXIL%V>LGYZYcfp$t}dgG(PUjlWr{eU$cOH~>DhQE<}wBm{&|c zVd@{Fc|iI3#Yy?ur70YqT7{5*IUG*%t@Z7T!1HPO6(DbVzNcw@ur8;|XI~F*Xz@|S zfk^Z2@)S~`a+uG%Ht);WwO&x*Y4YIwrVa{X`#c5!*OSdUQ*toHgMt;rfcyfuzjNbF zASIyVml{d(P^7%LxrMoRyF~jTW2|Gj7nf%F3r9S_t~?O+ z9IatRfs#;rIz>ArT>w-%hq}{!qn*o2G+bmQWy1k&3#BJenqrz}tm_{vfU_@W2;8Cj zD4KhJt--&I%5EBIoU)lRnk{^8o!dqmRZG6!skP!b25$2&v1~cA)vXv|9(&>(E1PLO zdr*ft6y#FFUFQ0~s0qcrtiXRtwwk;4%&HQQ727m-2N z&>+PP7L@15OEtnDZ6W2N(~3=x|4X?@OW{(Ct$~zvw=$;tuGTHLd&TBW#bI7aYg7i5 z0zfp#nyB1bOGvg=>ipShuX#4t)1X+#X>{rO-G@+Vr57l*79csFBJKomXrbGLhK$Tl z9wcxu5to4)aN{q-uD7BI@1qdG;qocKdh0jSWs!`6cRHP&Wfr|9LwQ zu(+g;P9f>rOFt$hz8F4^^`605nuaH?AaY%7IN?J(C7s>|{;wZ?aB)Vb=!D`PbQm2i zrCOnkj!q=a;(Ci0Is(*iCp`a>_s z+U{-PG+M*-F`PE&yu9$EsGi-5Q}?p&2X?}&bXnDlyyiA$I$BTy=vaqKbixUslVDf6 zADUA7 z*SUYLWxc*n=o`uVPsUmvad`@s@cOwIaKfZ-%vpkKgbH){sG9k`;6enK7&vsj&o)Mk zzcL2t_nOhr(3~x${E+(yZq$86DQJ6&o7@Y)FYEt2Um5(d`P-0iu$<36(C(^(O&j%X zfPf5Z)XK2=9TY{)P**RV26pJM<{Fvo;k-z7u~ox+dDJteQvv!Qf6;oMC(6z%;#dv< zT=h0Go*7(M%(4|BzJ9Pw>WNt4rvV5`ksx@d1Q~>&JP|G-Jac|Ji#pXSwi$pYI+=Pw zue=EAt`_uD;-?-3A&2->Pp1V$;Ex0gqNw9%4;zomAV6in%{17CMjl8{&z`~qst4<_ z1@Z}scxkf96x1VbLfA^we%70kx+;jK6?F~f;MuH3>2 zzIoQ)$keA%-QNy!59`;@6uA6+XOU*mhn)kEW(s^pK|$1iKumoBK-=Fb=2Y+V%O7*N zh+hHr)8@Chl;dHmVdwAf1>e7a_l3J9z5c&Iw_RKva@CpQ?r(n$vjaq###T=RHJot4 zumm0C@bjYBYA@fjPyO)i4%xNakNvMp zdT9e)PjXq?)SN2;C`s=JpeSqE!?;ru@2e=`9LMH!k1^%s)PH*GL&HCnNSR~r)yd~6 z^yR_u(r{r_0!Md1ujdT%*N(XRN&?tSH2g!&262s*FF8%Mh59zoporm99 zYL?I*j42Ok+2NE^x6XjOA6ptAdO@VUvBj@#AQ|=3)9}u1F~SQ?ztzL2CDaUz)J9BQ zKGnMqfpy{yCS^z(wXf^){`};TDv?!JDl0&4CjeP!A@q)*Q)crDR=i{V1N5GCR1G<6OxXG&%b(lw#`^x|&Cd`qoL z5C!akf15z`+tZQ<#m|ufx%MSt^p#|oY}T@;1G>YFi`3m>;Z!NXt2k$)LcLO6U{gwh zOFmUt6GJ_W-`S6gfqy@n^kuadgFR1G%EF38%so@N!^ckO-I&H1yvs9Jj7gW-`|cxo zuoOgRAEU_N(|>Nz%#4{tV!K~!qg#B{aS+CwB|rr#YLH{3cw21pYiV%Q*J;n9T9GIV1Nc8z`@W4CF*OqjfLnt1>Pcsb8KcRVH1Wh=Wp9_DHgTR@qd-w%4O zcC!|_E0q+^OfQ{p&9x|hL5!f^L7unr-eE{$s9KKKp>tQlZ??x4&Oh;MwMj)g@|x7^ z1K1AVT!uReB=QKDcyv=ptn*$B1M-N)_QJqBi?3G@J+BE0Qc1p}elZCKIv?*NG>fOY zH1oG8<4S*t5+g$0?(=@u`mpq^bn>B4rY)~P1( zY--aVFYw7JZH8}NFVi}MacJCA0E8rmK9AL!IeJZ@8{bonsjprP5qMmy0fC{V9Gj@f zf18c-!VX&a-q}t*5#2d>#-N{($~G&G*XGcwf8BrgK((gAize*!&2|1BX2QP=qIOW4 zQ+2%qh)O*+CNu4c@c{Rw1d>p`n&I?I*&0GEldr0lsDR`OJJ8B;0+s?D9d*5G@T7c@W6Ce+1jD$Ywrnse<69VBY zj`pyA4}efM$K~%5Q}JFv^z)Pj`Eb*L|I^I=+%hJ z(Jx@uEcX%>-HpQl5k%&il@=S|;0TD(LPSm_bwUXb);v>WViQRjAAVW77!uoxAtnUS z0qGfyNdu8+_=U=&OX+{E9XK>~eDDdj+^uTZ_!)FV z6W_<_)EZf7Zg2}|qC9y+4v2{X)2z+GThrS-0-JmUJGp*7!80cev+sU{!KBw?&+zfa z5uVvpu2d;(n}?^*9xLa5yXbqoObR=mVH0)wog&y+opqI4lTi;`VNQYJX%HFhrZj<6 z4trBHGV7QajCxMskDgz^G!v)<`^|L5$>+51!O2Z$H-Fcvarq^f?p%+dGCs;EIuquR z#AP%F3EMF4k*qOE?)h|H#4Gyy%u8oJfkedulckZwUz2f zSd{F;*ZP3ETjxB0^L!lt1}rLF4x~9O;>zhEKAw**pMHMKzB4!3&uz4q5+mr3uf3 zD7MMLOhu;$7C2Wk&(RV14U zsB4K(H|<7_?Yea2ivh^@c?uDT)~a-a@VS!44O0QFW3tDl`(O0*|EThPmHl2rU)nD1 zP>?1;Va9fkNXo+;DRFlrDnFkQB_9}?2GJ&SE`yinMU^58{Gj#y$;Ay3!@pBOq+^YV z5V(lx!t*a%zeorf4kxLBCe9j>0+>FsH701xJ&2U_EojUTVhvhoEFiMS!e6nwzMdKu z5*fT)kK%y2o-Phw#drN|sn!Ka&L+EG`)prw8T|BKL!ZR_;wR#YT4R(f@-$EyRct&~RweN|{QC6vq%*~BkiFLQB zz=Qp{i1Ibt^N_!B2h~NC5<$NCD)Wg+4zh z6Peotef|tz@gH9NG~?q>7&huqxht(6lJ)wt6ucMa{31P)t{W!8pzjBYT;N!sL|N`L zvJ)%e0~Y4s(XPy z%5lF#0dc-#;J^fQ3Ve(gyFE4RN`2^xM!Htfn1UE*Q#3ewLKZN#hfX-_0auy8`M&y0 z5Vu7Mc5UfcVEM_eWrB8Xd6CE9+K557yJ|FwvFsOKM-IeN6xSfBgyvu(kF|{~+-=c$ zV0q#vT2&!2G#M1oEMUeGYb-Q}z>meSf2ieD_@;sXT4wtC=l|P)%ch1Chx&gnx-K#v zD#@<<>JkuSuI){?R03R~1KkOqJ%*O(cMOWw*D49%3LCeQo64X?Iz<%s(q92(ycbOi zNJSijt7eU8)=SYEN5No*#sAE(V*r>dWB=|LvbKOz2XU-_g`&X3gQd0B1{*`ZukTf< z^5-A8=s|!}|83VA^5@Cm@8VmcJDF?1ipFRVbD>4v<7{kqrm09D6x|6RwlwZC}r&w`o#ws5Q@Dq1a4f zeh`rmxY1vL}P)CFBAIo!~RD_%st4+fi2a_PG2 zA4!eLD@qy~$$*KYQfkuB+4K+qS1?|#Tp1~uI`*4#Km29()NJ=d{Y>SHs-h?O#CMnC z-m!MHZRMH7Wcm%WoMyk21V4z16`CwfM6T9zntMmbY#q*T^ourqjRQ~A{B z*Ir(=jKJE6%g^$8>7jgPL^nrTO6cS2(#C0AOqWxs(;5YDmUOJ4oWA$m+p}L(puyR` z7cBN^4Ry+4_VyjNU0U$ba7XCp1;F=sjCW2?AsyWLf}oqo5eaQqw^J>$j28)ZSUdix zB{(t5RCc8kXB-~=RZE(U{I^;X&H7T`1DFmg1ybW$s|U@OD5c~llDV$&;yFK9FHPrG z!)c!^?JOF!H_z!v(DB$dnkKWNwy!hIpE=*A;tX$}wUcgZahJG7O1jJzE!m@Cqg`NS zGPE~7UQsD=G^V9l^Ksb8eRJ@g8_sK9sxUfYK}wr5vDErAmtJ8pd24ONFOHc9NkaFH zZZUX^FHeRax-_aZLCOmUcCshJ4rC9(wF18()9ei_{KO^+6?E6E(SjZQX*Tw+kdo?8 z5TPmo^-LMLw7u!)1%?OQKqCh}O%b3&zgN2wyv@J1m$mUUGgdR(I@I51XDHHRXT_Eu z{l$?Ze`>fsInrZre&_N=+Zz4GFT78VRie$kO>eV491I9!i+ABOeK0qBe0#%M(M=yn zr8)2@A0ytTvc?*0_gqMr7mJtj%kTx2G&XmysI>9u4&B2L5313sEXos0y!O47*57{@ z*noyP3T{ZT@4L`{sw%-<5I0k)$a`#o@?<^gQm~e~Xsa9wHbetYXA+rwju9;GQRQv; z?O@_uSw0ufN8PbDZ*DmfAD?4UeuaQ;$liqSrO7q6pI(t+O%xUGyel|eU^ zObt_cX3I+V9*mHB=|>&8Y4a95d-NT}&UPuOosv^|6z!gR@CEB7Wqo9+k`Nn;|J<&n z6{NiQx%z8jvOWUIOrsdBH1wz;*C_Oz)kRQ+dcI9Dg&fLw)|+$oj5;~ApOVfs}ra@e$buEgqk zSB(9egZ7L_heR$u-F0rQoux_kU8%j-74K&i5V+~ft1~r0U+avIx`cs}tUd2Oq%IfJ z30eQn2}^rlR$%>$=E~?!tbe^~vlytw3oXy5>i#$-xmnzOW=2vpQ1W26z2P)N9Limi zSkp8hAZ zfMPMaFfbdW3wBT7gV|%wPutIDAJMG0X=&n@oV&cmcUKbf7`%-3HJ)p()UOB&R4Jsp z(%}?&n_i<3bIG=Q)uTXe2=w-XE@iM;o-6I9DwdriOqXw?g$yJxUZ23Vm5QkBnrQG= zEUtpp=?*vd#CES&+beAy*!q2Ayb&b9tmr4s2G%u+BU(MC0eq1bUsO!_c+i7TGggc5 z30WH}Q@dRUdL}M4*QHXKqQ{36k2Y6|_@C@t_`Ic3XngBU-Q}diz4JsStKT+!YZmv# zr*Wmy$@EwYN}V1lw3OJrz6&`jyLa$81FqHWiPXkca#iQlzdhN-wJD;6SL<58Y$)ce z>lKfLdQe42%4b4bMl%2a?m0b>qWh7j4*DGETTD)5W7bXw08YCyfOfZr30|m#v0!;c zOCvl*)%tGY5+XZme@`4s=oTvg!9l6k6LAmJ&E{YiNX}3*{nP<}EA=VdAGu&XphM~Q zEV6Hc6Ek1=E>o&%uBfsuRKnR3eg{%g4!8+jIFL51k{IOnICD_^5zu5HyFCS~)PyCW zGxDh)4|nYvuzxS@2$pCx*cAXu);mlmO4dL`Q7Xr~kLOzA6fi^_ji*xnxLWV;1F_8T zZjJztq@1ZALv%aLsG4_}YmiK|%oVclvR+s2#&X=e0bR#62_z@_FaD&&;3BpmaUMjv zeug|OF_p8IO&x%4+y~)LC*rCT&?h?VpDEHz1D{xl$1a^n)imFLWECIIbW-f4>Y6Z{ zVm5^E*dL>6O=O<4-GgS@(0m@TgFih!h@rX30N%N=mq7F9ox3F9olbXF>B0i?`$rrpU!?ZwYLqkv={@$qru=KBPOX5xr6ddeI ztiXLSfB&CgGNM>=WlxsUUnYtu!b7)QsV{v!ksF>UDioavKrc>XL}QRs3Jf>c28TeF zt&}y<&YPk#U#!dLUs33h{Qy@U}JJ!GrQ}MCIRMpSXKANjx#X18D9r z5e+U$fE$Xe?;_+4Hp_!Am>2Q^=zSsD9~ag;<%91C5^czUq66ug^P?uSUAJ;wEz}C@iF5J0_r-7P~HcU z3A5`HG;A_9}z4Z@rPv_Q32B5Z*x!@i1uwiY)qad0k!w zj_MB}@?6dj891FC$ zRtDPloy#84zJ)8d9W17~YuZKcGl*8BLjY*BzMW8E=asKw?km?r#4tVNKC@HIX4aEX zayPQ*_8&F(xDX)nIuMrWW~P9M)3L$jnsEmOZ=S;4CPsm9Y>fDWzq$efzU2VQC8boqSQUfo~4@y zO$XZ=;Mk50sRDf{r8|V6f++5`bQ>OJH(on%eX9uwXQqHE)lC$PP(M@3N0mGP2%WS8 zFs)5?4`5$gpC@^Eo3WLO4HpTJHB(RG@s&LHLt72 zmV8lp z3mdx-&;-gF<+T6WIb}-?4wjpFwmH8!{MdXQ6(YC-eEd+%iKY1*uBCO1h0nkm{l6+N zAGkBb48NgP3e@sT#`V33?mVA+#p@>R>N$$FD-3GGV{V5oh~bj*t6au63(rLTON<$G zO#qIDSfdsChzU3v(WPa7_g8o`yTfxPX`dS9unvc>LgiOcT~ea5M{dfLH5*APZ_pqm zB*bZd5{3V7k!pBzG5M;}EDEo=lpy`wZ!mch%h^$cKRA|9>pSxEh7+>Ny9zH+ziH!t zIcgNl)b?e$SM@D7=?l7@q&(a#ap2)aBgO0n-w$_|S!b)MC#4eTd+`7-I-Ppso z(axm;;_AT0P$(e;OH^w(7`>zc9jfHMx1noHuzYfpweOdb~x@iK~eqw47$fYEfBJfov zJ-UXIJtqI&ur-;|Yj&~+iRlT{evBQ?3V$uyf3WZzpP2q|k!~;QaBfL?oT8+VHt*9e z&D>^X$n_F2^{D4_9tFj&^%bJ*<=Sd<7Zp%vR(;TlCr$}-Gv7SNkDpJ7-{1G&?V~Kd z`qyGBrTEh`ms#SzZ1j$1wgq4>x9chD^g4RRHm|ckSEPMj-I(q+Sm5M!u=>U4u1rNE zBewqT#|lV&RE7$g3927jLPTa{-y1A!{$6~H-`N7f!p_eFN^2)jH`v(R94~H9wq(IR z7kw%SX-oQh6a8i#m#j*-7+^uNX2PZtHTQQ*lZ6B~gYLdOq*A|Mk9p2zI3446zicY0 zkH3`YDENWKKwo0R2EIf{VCpilMe3ddnj(FE5wLgmqfD@%m&8SD-PFu>1sy;_6^FT|a66y+GTP3A^(JF8Ke#nCB73 z!bSJIdJxbumV>Dh!<;6ZU}^TAZ@7~s|Hp0yFp^yZl^t+}x5#D8%*-fTTIPmI(TO_c zs3Q4UiH%iN7-Hav4@xK6;xA1=$XLS>1l{l2?)*+OsJp%%l^;c=h*52esvP7f~9$( z;J>Y~L@tjyV^@V^fPR(Z%J*Qauv4Db33q?=MYKHW4Ce-zMPKjWDx z?n3NCQsVzV8(yEnEMta9cb@`!&W0nc>V-8#6*!N&+3^K#GeQu>k`sF(KRySHuc#~B)8=3kCHy} z;Nawp1EfK8CGUB#oLAVJ&4iy>NkBPUXj96V5$QWHVy~p#8H08i;}_z5Zri?`(B}Yc zorTH-5F$+z6ZL*rRM(l>MKwZhs|HctiodND$Zno&lzXYzEl4#Jq{TtAk6ozQ2Zj3G z4@;og2a+qF<0>Hu#p63^xB2Oz6L7M@?w$M{i8_t_NqNefD7_aBOu@u&oVf$|-Nohg zEZ2Y8ij!UYQ36d0{ltj<@vfA4sld=9Edrt|%-~y?{?va?zU9ivx5T9gOF+Im<1VrF z77S=TLN4}_Ym#@1Mzo}=e`|5@xnT53+;obF@V@`{*$r++Eu=k|4ijd_itPJtB`_Xu z5xa!2WrnZG=PoM^h)jAEgo=(Q8GO0HUP&hybC{H;{BtMJ$tn4*(|uoGb%CtSBi3fK z!6tLXj+0OhpsAUlBRQK~^FSQ@B$Mp-5w;_PAJHq| zyeO@`g&mSM!~E#{Cwc;n7{TIEDp1@0E3qb6aG=L_K%0o5{(1Y9VsA(=QqFf1YDI<+V%)4w8?6w%{KRk`Z*If-G)hM!g_t z6xAjbpmTa(`GC&5CiPv-e8cYa)Y0kbo>-PAH&7B=ZX64v>};>vWrL>+pR`zdl+xvT z550Y|i$K0)Q;nmx!p23eHge^LC%0h)R9Hctn>OpS4fay9YqBQ=d;jlxQ~RF&E;SV@ zmFk*Je4oV#@(r+0v%i{gc7F}RS#a~npe!A0AAuw%nIIvbv0tRi4WZ9DYBjC}#kKZw zu@c6b+{>d?LIX<^b$YxE{Mxf);=Efh3;cRJW;T+Jy?;x8dA_f%G$E>S@!F&0hd=0R zYYGb==xStgCQEEb1RKa}F*`2qs#~Hem~J`__bW$a&b>DhqFFoZh~j|kde!g0l1;w`_#|pJI%h6<_$60}<|U^4S!N}tsg5$n zY@Tc`rz6%=z-XTl=bmXTsBF!0PV)ZEvZ7Oyq zO-s8KAS;>G_;?gs^-6oqBX8nVv>uk${?3~fr}W_(DiMf#+Oe}dTi1$1x1G5mc5Qtq z`?bspgO|5{LWa~EJy(vRuhG`O0>Ga^7za?)=kO;4uLq?w0 z64f!D9?s1W50;CMyj=HdEb2=eh82fyk9_k*Zk(lyqzocoYFe zDN+@wqJ$z4Iz(FNih!ah5JHzGp(82+qJ(OQ1QiH|B1!^E6OW391PEON0+!HwKm>yV87BZwDpPzjEAw21tVqpA;jQX zm1p-2u_%85;(Evd5cu{dXJYq2haasBnrkjJGN{I(-QSHkXV-s4Ym%;u$vx5))y@@- z+P3Jw@`o2e-83*Y?(i@UiK9dkm{gbu2Qk)4jjd=mg3i;X(JWVsdIcs=C78~izqE=j z%p@mxfnxoKW&#!V+4U%ol{BzA^er>n=X~w&Ib!sJi!Ofo3Aaix;#0~}ktCv>=vYzLA!B)S%$IQR58M;30teu^c7w4}Lz-hcba&YhWw1NJTE${UJ( z1k`&XQe%0Ffa;JM|K$RU(GjH`Dkp6;A0Skc(=jnLVHM|9Pp<@+~EcU zIas72kzkBr?z%Mm_OAq6>wd~wVUw1hJ-st^Roc2aF%rm$tP9B& zz|cm`Rxrf-)C}0QylRri5Nz@WQK-;wbz133gFl2V)ZJ*-yEz6X%YNaMifj$uha5aB z#3A#d!ne^k8l@eXzbpLScrJv#^$9D%Bc0v=+6r)~NHX9Z9ja9hma1F69Dv6&}BXt@zSb zpK$zRN}c2ZUhwOAn;!&Uf$%~vQb^^(WJ;221i*q|USU7P+v$h|o$fFd!_HZd~k30AW@ntHpUI3zOIQ(bJG&b4e2)?a4FgGL^}>c-c#x1wAk7T?(I z7uOV3KY8LXXnUo6NfL=yh2`t11XNop)aZpU>JtTNO#>%S$BLZ}dj?-vuY55&*-KKO z3+m*A#JalvN^iMz>MS8V{AG8AquvwE3?6ILWho(t&)h60L!%F^2dLcJc6ZNGRUQD> zn`S#Of-Tpp8Vm`$BBK&IwFSurLd{o}q;puzw@)@$FP#>yC7(QmO36OS-K?5r@3=U1 zGGhjJl`EI$M1wi8g$KzK?b(y-n4W&w*;Ji{>s|R_K{wjC+govgEQS%BYUBl5v;JdA z>tz^WvjYk_yh8H9Ge=K=c!u07Jy1OLPpo~yma=ZPq)0VRMc;v2gt*t}iGVoinV=Oa zV=m!}8M)`s=~cF%6_$$h?hBB+It#N4&djVrZZyvolPSM84` zPFLHy3Lg&}ea+YTa_*wjvYz$BH5B8a^iP=wS(iMtP3UA!x{&S2y~lP2s{WlvR(!Wm zLBDa+?yTto_b-@TvqE!wy2>Sf_$ZtBN4TE^yu=!C- z0Ha>FY%63JlHvnDCz@M&zWjx$w!&OyIgFDRlRbw2uyKGYwmt7tt-9WT>yNUQaAYw< zrIT6X=|9raCiOO5VPOk0R;J#6Vo_#pKP9=10j|wX`o5cUo(fBSzItU+P`a#4G1p$p z5s@k`bnf?*+|W^T6Nf+EpWTOjk}#9ziNxOq`}wc**GyiPOj31cNn~)6a)=l9i@**2 zr}aJV_-!i;H)7!Zd|5O+)ztnH1f26{{gLd^3C`sT;kin$lp-6p$Cwn%1#9kHUW&f>I7jU6=F|OUSQp3#Tp3 zr0I}jP_#0~;`{aRfahOUT@D_kLKtDz|8-d%pFfsu>GAb`Wu*-UE&4Pw8MFpC9tD3S z3E~cnE7#jj$|eJ@9X@vD!Yy36B0IQPG>9fPs_WVo>D!GX`ao{K zPkJ&oV=pGVbMoW+1K@OE09J7d0x5>z@xMxZ+l?WzX^6X;$9sH4)J>syKh|ks5Bs!V zRKg^B?e4-GrT$kI6e_v8+!+^nu5e%e@3=B2iheHWJxb{D85y%hbdMLMD^}YfwAOMZ#Jz+KZ5%=Yv;#;yX&z7`e zLWDWg7gz`oIqMUSjXVR5K)GErQBulcqVluey)%?KcZa+C7~^UY?EDFaYA3yBeshfP z2A*4`csV&!r|(jhy>LnOn}=^A<7qbe#s068NmxD9elY)8$}_gpwwrRA^_i-5Ys)Bounf0ry}soHOEGt8wi zSWi7qK%SwsRhTDwCj8X+qV=m$L3WGZyUhIkV5F83c$W`Qvy2SQ-&JNgX?dPor9U$x zG>KpYEvz*2^(H@|5lHn20FED!mL+Qk`# zqJmi!wxx0^f7dhRER;IGWx*$@VJ8X&DdI;&D6;~;2c8qK_Bs*-N0%B%yqMC@u;zWWM$*v{5gvT?ad z*?q7cQ|a^h`Dp8}t zsX< zov631W_RGh5He2DPdiKoo~&V=O-F-9WlauuLdV(-v_dD24b+BaB#K2)O|=dMfyz>P z3o*tjUw7cHHd4F?!~ud5)Ea+#>;Fiw0^6aUx#qWcvG(IY!0-oYhVSA-LMAC^!NGFi z%hnwBednl#Mze^>mJF|zJeF#&>eok98ZE!E>2}NoS?t%FS&io9eBt*(4!??_P+^hz z!S^09F2t*svo_n6s;9C19fMb-d&{nr`ma|Z)mv5B6r>I&xc{t6tHGY}ALxEDA`WLxX{R_`Tc47rLH?BJr~@fLNL1T0h1JIaLC@6(45g>!{^$P8LdjOtrS$ zC-I#yxaH`+lOovOH-0YGtwJnZ@tuT^A0#0E5gJJ#WtyL5F~QNZmhKl~Vq#=VkS4g^ zjRNrvSxRFrY_$xuHw>Dt`kWknzJOMCOhhZhOLn4VzfcEC3WOlnAnpsCRM-e7SN+-T zB|}Ry?2c0x0FU);&oYw093x*S_M7-)v!hd8dI?TG;axISIsQ0*YETKv({2oOTN7Ms z?6NKK@*4NW1p2Ni0Z`j9(WPoraghqExW_g9>^`)NSkT61KQ0~hY9I`c^^QO%KSLCu zSx&$yfub5>YB-{V7+jx*8efT2>_rotYg1K%3GiHkGwd=CTXCU<#K)<|$IXr?Ainv$ zsKYLkF^mH5EDO$2(M*0Mo~F7}pHL(u+f-vHK}}&!uyBZ*Olk#qlc*K38$RT-PER8V zJqIzK!?+o;AdVoU;AgKV4iA5kipiHK;N#&yP$?6HuQM$p8~(r9ars@;FOH<}FkaIjkDaFs1?M1q}|C z)7NKF7-@D(&im}(RL|4+Jjok~H|V{ptH^?mAWb!LEtZ-MPl4})X_JThovW0L5c^e5 z#7&sx{TBWg_9SXr4|OX~q49OJu-vtD=8)y&3IGwqy_-f)uLctCV_FaC6uQ&O%Dx*C zJof1vGLn$lhR3eF|7Um%=h$X=1Hb79d!s1|F6nvi@Q z{%TPhS|dyJ3dSpJhY{ZR58L4MxUNq)r0IJb%MH!xp|ro(?tYW64We^sqdj`)4cJ#z zGx@x(MGwob1a1jIXgwL@aOdEF)F@?E_JMMgB|zL0<2?# zrk=^(lmI_NI;Qv(Nv~eY3t}%>UV16TpzQZ>+vQp<{W}e{ zxw#hCyL+2Ub2^1mZvafSis9Qywr|r!k4jYE&PvY?PW0gG>xPyf45ydg*_ZRZ!9R26 zQk~4AF9lzv^xv4POgi0|gG#ovA>MZY`~xyef>E5Hk4BTeg67J^XV89-Rcpjl$^($) zPnsGIQ2*RU(k(5j-XMeFgfbYa+rCg9kZ#QHGoQWC@`uN~vt&M;#ENF&e z4)BQSQzhJsi?u@`ZXdOU0I^`tmv<91KD(N99OV19mm+C5=wEjQzmsa6%0H}>C!UQM zzxTD%%7-@6ZUAsZ~^2io*_or=*sybwyr|{aHaJJH#z0 za&dyP6kxWm*yqlG6cBgpn+c}+zj28{?>z=Qe%(oZ0&x9iEnu_~o>{o9y^wve`Exew zL{7!2AwY~t9S#{gAc!F{ehcfIcO_^zS_LpWqh5LbB(`q|=Mh6MYdob!5%sR*@ddO| zVH>)A3pmlb@CidglTlJ+CGxS$D}Q#MPlZRFP&Y4!(YMz>@58XD-zAsosv((3=dVn< zjwHhu0(&jE7}CZwm*VG4R_yd@&*@z_8X0|jDY2Ck&r>_vrPEoklm%LkxwffxTtMUH zSEZ!C+u=Objvo1z8IF}Bk-G6MWMPbY_{V^BOeP8t3OU?kf1LptP!K63_Anid-xSkx zhN$7VxX&!+OhaUm#q66PdZ<2Be@*s=b#O}eaSeg`aadcx)?5^?pHe{s{muqRP7Tn zw0j=iUoCW`YPnRO(8NfFiU8cI{$DQuhPh=)QTxET3F za|r=>wGYMw9YE(|rCMnJqTg=)wj(nx_tlX3Vq9y}P_DxJ`an4)92YkL=_&KZbANx^ zQ32?kXK?!@)rIf;0vN$r0xCC`^wgYJ;GypIJB#(CM6hFW<~s4`*ukqH$31Q2vvihB z%2jVt?M3537H=wBUP+`N@i!ypu6R7uZ~0hnMDPH)H6S>e`2kt6T^x^pB>7DZBZ$$D zvnMDyy)iuh+~u%&4`oP4cV0JxhW2=P6s}OU$k?~AP&Aw6c*F@T;)%K&iKz>$C$H!x zqhYGHKIbW#0Wa9TZOhl$3oicqO0A`tebwH#;dGov;(aif0dyQ^L?6^B7arZ`iDX-9 zEIPjQus;>h=<%?=W<0gMIY+(7-d;0c2G$-`y!!y4Glr%-Jgt9F(71rD1*N3w`8UK= zZ~4(Fq2QKHRK$c&y41J0Mu{EL4giT3{az-jW7D_)$!6yHl!vM;t6 z2qYzhIH_d!XY+poV%MGvFcM$y!n-KQR9Ui})Ek!_WIkCsWGwa^cc!#bQ@J zEvP!f9S_bPp}vjZ*@Vb73Db4~Y~zmy+5Y36(KQb0Y{eV|{*B?=EiT}U#f>6><-N9i z>%&%5*`+e5!*~?=kcr$nY=u)?(pfi^ZRiv_Du`(u7;TZ;cbkORv18wWnX!QbQ`Jv3 z7v2@!_GO`EILT}ts=dJx65Jrp0W7=rI(kTyg_})G+pjNC41!jW_v>-6 zvmotHfOKHf2@8}~mkMy$*3x@kkNIvnPhJX`4CnC?xDE`!PUL3_9|~LS=S?HdI0BA! zkfYFx{oKZT&E{FlT5E{xzk?A%#p@Ek`@ID!>O4it6kvz*MA!;e6v)!tzyz0@_mX75P&)oZbS^fYXOJM-x% zt3^Ej(A9$CFkOf@W2!`a7zpy&l6=C@RT`3pA{B&U7(aB%z5%om)b-7^a>h%dw&9#$^gInAdV*pdu1P>@U`eTf@yWAQBfT}5JgBpFhY;yL=<8H9k|kX9c(6Dp z`HVv6Hb^-_mQuC@;%Z`)ivU}(>jQ}wXw7Z|8uL&D95O{N0N@tg?!!a7FgZG*!Oav> z(9f~cD)paJI~#l)t=kT>a3>OPLub3|9!pcgcuF%o59`SrCHrH8`)*`@I;<;`_&`+f zkg>S$z}2U3tWKUWAzZFC%vDDVrk_)%O#(XY)`x#!3)lY(Y-urn{(k{2N`0zH#|L~d z#gEo?7QlHMx>3!bNFkA?1{SjHNih%~y;TM_&`c+zP}%0788JZ&bRI8GO#BEvfYi4` z7$Oy7HR}P}CjFPg<6kpOMxna5arQ!^nls>YddtwT3@y!Zf?Sa6r?wFxm%-`>)pwpY z0o>OYRV+nAWN1pib;#aer_=8pNs(bt+O$8Vp1N5cvr%u;{|No4d4F`_vy}7u(fH=h zVNGC>j=;?ag|f!~#>&bdShGN|zH5Wems7&N6W=iXr~GEs_sUNJqOfS8lg78RTpjm` z_)EQ6tYi@S>TCWXdPI9;MdW%<>0RD@J)!n;iL_if?8W*5Vxdu}HwP5p+Vs#T9>9N5 zx=ZcPf@uGla{N4KyFOHO(mCg|0h>#L;V8;^`!|94ese5$DJyYdW z%!V4di1btyN8R|ciEi8I7W^B&tXu8AY_FcUzxKWHo$(vWZz%9%y-%kx>a$O7Bc7We zo)oEIDT5HclA5}jbsLzo3S`bTraLg%DFs&fAeFhr?e0QAN3i}ODz6=5zCd>kPo%^G z(rxzPX59L0qB!jb$=-4+B2`EMHlvu1|1@-1=F4K;(>FuJf-iJhO|wye#?UYE*oqZz zz;*S|$SG^QX{9GONiFy@l9q!F)ouxyCtao5D6M<7Lbw$yJcc6st8pkYMv_r!mR}2Q zLV|BD8BQjp^)$m!t3~$>2DCz3Wwv}iSKODQIuMY675An3%8wDOmrNfFI_5gqMrw8$ zUn}xMq};Lyv-+S_CgF?$&R%Xo6xdrSFtQpg_9ED-a2Ky%J?!LesrCrV=b7&{1x~eq=FOt`~AIaEd`7!(v$LT7#ktp&tLGd72ngXS@LtOh^v+cRCVDu>*J zCBw$3d@mU$Ge#o^gH|uq15WR~cRH$1w)pV^ZOQ=XwT^l11{&ZSoH2k$2VjiB-C)LJ1^r!7P=&(QZP>$GQhd3Xx^5DY+zdG43t_G;1|;=BJ? z-bgLj08Us2yg@2v_*#IOF7s2X;VJicf|F0~Dk0(XfHYsXqAW9|ZCaLBX`?adai!hI zKVLHoF=QylVi$9lc>pSP3fW@`3`C9N%0DybHN<&X;+x zr9VJOCcrU7E zy_P?ol;1|jyep3J-<7Mwq53yiK=fO;61Yk_Pv#y2Z(0$l?LByk{QwmWe|y~J0er$~ zPS@!E=qG}SEB!U<~?EV^y%R2C|tsc*rOSE_xZOKJ)3 zV{3Du@3SxMT5#)MJ0j4={a@mDT4LIE?gg(RakuE08wZ36L(j}IMv@)@A^30IK;Uyg zPZ6%l>VooQ5Asj>Ek_2nI7!(I5bE8iT0w_^(0*P_@(Ma;@DI9@p}| z*Ijasp2y=YTg7gdBzJ6rYI;jjcGuajlEJZCmR_?jsLxIxy6opt#j{5x%VDWyHILMU zs~)enrazpU6AfncyHwvA7`0rh|Ft^lJ}|W9wqK&1jsd4oA7gBTspL>LN=DKVh-N0n z?T6Eg3C-?R-Ozq!i8QX85)5C;!-3@?L?F6b$T0$}ekVPn6RiFX2r&;^jDy+S!CfZY zZrwNZ#RAA=>~=&5H0;Gj5_VM=@Eu+I@piNl-F$Ui{YK355L^s!MW7t3e}IMa36xzv z0wIQ7z(7xcFM6qhe&9W*G`#YYmDIVuyS!*#$gk2aRz|+{9Hx3{qqTDFeYssYW7+Zw zaa)8KFEh71Kxe%Z8*ScG^?)}-Z~Wo}*Zr84toqui(3+J^G16hg9tdfvKyMib)!}ay z&F{mG)X~@>Sx5@gsBJj;KoXL|unO}Jnp=F#WV;}y4PIZ&Dh%qZmjF(f$FjeNC?sk(?{ zUfh~93i|$YFYDHNRE2s*7^E+n+ZV5~xn4cBMKSCP@tVe~cePI)_)_mys`_^c_k5VJ zemQjG`~YxS960g{0HPYRZwW=#wC{c{NxFO6=X|=I2F{lcC+Y-n+fZG@l5_V z^$PwkHP;iSnDtI=3Y+DQc+)!Qy5;n@eWU8M(MW~imMz`)In%`*GXmkG6|;0RkQb~g z>>a28?T5jIg-Kv4{tjc@y79EwXsLhXPKJ+H!e5_zG`-v(F&;Q;+`KkO(w*6ZgoJ9} zkeszk%vd!)Sv{}Mo%nr)=bWVHzUx)f8}$Ylt|%uF4tany(~pBW$QEUQiPJRG-_@sG zblh&MZYXOO^eBydyy7J|CWaEPxTLUKZ_TnzRG0JmNWsej5_o?axkcfD7d96^c$4ss zpQd6zj^j6l^)#GINx8KQ=69MjI|W~BzVS!sz_U9lP(t|{0WhktGY=T_rltOp{@PfL zp6LR)EgMnpVi98y-`y4<0a}9b1igyxc~w#(zf$=l&LK0a`AxZt$5MYlGuqL$RSfk; z*hCm0xn*1&G0;CI7*9F#(;XdTE{$%N<;9MSav)z!%eU;GD$Qi)t+{_%0}akJ%T0SM z(uEm3Gmwe9C2azI0SJ%$6hvRqJ{c6?Foiqu=yG*|RSs0e^ zNBR(375(*%jnzzNmc3en_SZ$QH)c+jL&x|Eo%q1x(})W5a*Y1{nE9-;F6QJ;Muu|VYLiPW+ -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 0.13 | -| [aws](#requirement\_aws) | >= 5.14.0 | -| [helm](#requirement\_helm) | >= 2.11.0 | -| [kubernetes](#requirement\_kubernetes) | >= 2.23.0 | -| [null](#requirement\_null) | >= 3.2.1 | - -## Providers - -| Name | Version | -|------|---------| -| [helm](#provider\_helm) | >= 2.11.0 | -| [kubernetes](#provider\_kubernetes) | >= 2.23.0 | - -## Modules - -| Name | Source | Version | -|------|--------|---------| -| [images](#module\_images) | git@github.e.it.census.gov:terraform-modules/aws-ecr-copy-images.git/ | tf-upgrade | - -## Resources - -| Name | Type | -|------|------| -| [helm_release.prometheus](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | -| [kubernetes_namespace.ns](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) | resource | -| [kubernetes_namespace.existing-ns](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/data-sources/namespace) | data source | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [alertmanager\_tag](#input\_alertmanager\_tag) | The image tag of the alertmanager image. | `string` | `"v0.27.0"` | no | -| [cluster\_name](#input\_cluster\_name) | The name of the cluster into which prometheus will be installed. | `string` | n/a | yes | -| [create\_namespace](#input\_create\_namespace) | Indicates whether the `namespace` needs to be created ('true') or already exists (not `true`) | `bool` | `true` | no | -| [kube\_state\_metrics\_tag](#input\_kube\_state\_metrics\_tag) | The image tag of the kube-state-metrics image. | `string` | `"v2.13.0"` | no | -| [namespace](#input\_namespace) | The namespace to install the prometheus components. Defaults to 'prometheus' | `string` | `"prometheus"` | no | -| [node\_exporter\_tag](#input\_node\_exporter\_tag) | The image tag of the node-exporter image. | `string` | `"v1.8.2"` | no | -| [profile](#input\_profile) | AWS\_PROFILE to use to apply the terraform script. | `string` | `""` | no | -| [prometheus\_chart\_version](#input\_prometheus\_chart\_version) | The version of prometheus to install into the cluster. | `string` | `"25.24.1"` | no | -| [prometheus\_config\_reloader\_tag](#input\_prometheus\_config\_reloader\_tag) | The image tag of the prometheus-config-reloader image. | `string` | `"v0.75.1"` | no | -| [prometheus\_server\_tag](#input\_prometheus\_server\_tag) | The image tag of prometheus server to install into the cluster. | `string` | `"v2.53.1"` | no | -| [pushgateway\_tag](#input\_pushgateway\_tag) | The image tag of the pushgateway image. | `string` | `"v1.9.0"` | no | -| [rwo\_storage\_class](#input\_rwo\_storage\_class) | Specify the storage class for read/write/once persistent volumes. | `string` | `"gp3-encrypted"` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| [alertmanager\_headless\_internal\_endpoint](#output\_alertmanager\_headless\_internal\_endpoint) | n/a | -| [alertmanager\_internal\_endpoint](#output\_alertmanager\_internal\_endpoint) | n/a | -| [module\_name](#output\_module\_name) | The name of this module. | -| [module\_version](#output\_module\_version) | The version of this module. | -| [prometheus\_namespace](#output\_prometheus\_namespace) | n/a | -| [prometheus\_server\_internal\_endpoint](#output\_prometheus\_server\_internal\_endpoint) | n/a | -| [pushgateway\_internal\_endpoint](#output\_pushgateway\_internal\_endpoint) | n/a | - diff --git a/lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-prometheus/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-prometheus/terragrunt.hcl deleted file mode 100644 index 76650e5e..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-prometheus/terragrunt.hcl +++ /dev/null @@ -1,61 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-prometheus.git?ref=mcmCluster" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20s"] - } -} - -dependencies { - paths = [ - "../eks", - "../eks-config", - "../eks-metrics-server", - "../eks-dns" - ] -} - -dependency "eks" { - config_path = "../eks" - mock_outputs_allowed_terraform_commands = ["init", "plan", "validate", "destroy"] - mock_outputs = { - cluster_name = include.root.inputs.cluster_name - oidc_provider_arn = "arn:aws-us-gov:iam::123456789012:oidc-provider/mock" - } -} - -dependency "eks-config" { - config_path = "../eks-config" - mock_outputs_allowed_terraform_commands = ["init", "plan", "validate", "destroy"] - mock_outputs = { - rwo_storage_class = "gp3-encyrpted" - } -} - -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 = dependency.eks.outputs.cluster_name - oidc_provider_arn = dependency.eks.outputs.oidc_provider_arn - - # Prometheus Configuration - prometheus_chart_version = include.root.inputs.prometheus_chart_version - prometheus_server_tag = include.root.inputs.prometheus_server_tag - prometheus_config_reloader_tag = include.root.inputs.prometheus_config_reloader_tag - alertmanager_tag = include.root.inputs.alertmanager_tag - kube_state_metrics_tag = include.root.inputs.kube_state_metrics_tag - namespace = include.root.inputs.namespaces["prometheus"] - node_exporter_tag = include.root.inputs.node_exporter_tag - pushgateway_tag = include.root.inputs.pushgateway_tag - rwo_storage_class = dependency.eks-config.outputs.rwo_storage_class -} diff --git a/lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-tempo/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-tempo/terragrunt.hcl deleted file mode 100644 index e1b17d6a..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks-tempo/terragrunt.hcl +++ /dev/null @@ -1,66 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-tempo.git?ref=keycloak" - 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 - oidc_provider_arn = "arn:aws-us-gov:iam::123456789012:oidc-provider/mock" - } -} - -dependency "eks-prometheus" { - config_path = "../eks-prometheus" - mock_outputs_allowed_terraform_commands = ["init", "plan", "validate", "destroy"] - mock_outputs = { - prometheus_svc = "prometheus-server" - prometheus_namespace = "prometheus" - prometheus_port = 80 - prometheus_server_internal_endpoint = { - hostname = "prometheus-server.prometheus.svc.cluster.local" - port_number = 9090 - url = "http://prometheus-server.prometheus.svc.cluster.local:9090/" - } - } -} - -dependencies { - paths = [ - "../eks", - "../eks-dns", - "../eks-prometheus" - ] -} - -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 = dependency.eks.outputs.cluster_name - oidc_provider_arn = dependency.eks.outputs.oidc_provider_arn - - # Prometheus Configuration - prometheus_svc = dependency.eks-prometheus.outputs.prometheus_server_internal_endpoint.hostname - prometheus_namespace = dependency.eks-prometheus.outputs.prometheus_namespace - prometheus_port = dependency.eks-prometheus.outputs.prometheus_server_internal_endpoint.port_number - - # Tempo Configuration - tempo_chart_version = include.root.inputs.tempo_chart_version - tempo_tag = include.root.inputs.tempo_tag - namespace = include.root.inputs.namespaces["tempo"] -} diff --git a/lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks/terragrunt.hcl deleted file mode 100644 index 9eca1de2..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-eng-eks-srn/eks/terragrunt.hcl +++ /dev/null @@ -1,28 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -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 - - # Additional Configuration - tags = include.root.inputs.tags -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-cicd/cluster.hcl b/lab/development/us-gov-east-1/vpc/platform-test-cicd/cluster.hcl deleted file mode 100644 index 8d2831cf..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-cicd/cluster.hcl +++ /dev/null @@ -1,20 +0,0 @@ -# lab/development/us-gov-east-1/vpc/platform-eng-eks-mcm/cluster.hcl - -# Set cluster specific variables. These are automatically pulled in to configure the remote state bucket in the root -# terragrunt.hcl configuration. -locals { - cluster_endpoint_public_access = true - cluster_name = "platform-eng-eks-mcm" - creator = "matthew.c.morgan@census.gov" - eks_instance_disk_size = 100 - eks_ng_desired_size = 2 - eks_ng_max_size = 10 - eks_ng_min_size = 0 - enable_cluster_creator_admin_permissions = true - terraform = true - terragrunt = true - tags = { - "slim:schedule" = "8:00-17:00" - "cluster:size" = "min:${local.eks_ng_min_size}-max:${local.eks_ng_max_size}-desired:${local.eks_ng_desired_size}" - } -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-cert-manager/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-cert-manager/terragrunt.hcl deleted file mode 100644 index 35e355aa..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-cert-manager/terragrunt.hcl +++ /dev/null @@ -1,40 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-cert-mgr.git?ref=${include.root.inputs.release_version}" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_name = "a-cluster-name" - oidc_provider_arn = "arn:aws-us-gov:iam::111111111111:oidc-provider/oidc.eks.us-gov-east-1.amazonaws.com/id/0000000000000000AAAAAAAAAAAAAAAA" - } -} - -dependency "eks_config" { - config_path = "../eks-config" - skip_outputs = true -} - -inputs = { - cluster_name = dependency.eks.outputs.cluster_name - cluster_mailing_list = dependency.eks.inputs.creator - oidc_provider_arn = dependency.eks.outputs.oidc_provider_arn - profile = include.root.inputs.aws_profile - region = include.root.inputs.aws_region - cert_manager_helm_chart = include.root.inputs.cert_manager_helm_chart - cert_manager_cainjector_tag = include.root.inputs.cert_manager_cainjector_tag - cert_manager_controller_tag = include.root.inputs.cert_manager_controller_tag - cert_manager_startupapicheck_tag = include.root.inputs.cert_manager_startupapicheck_tag - cert_manager_webhook_tag = include.root.inputs.cert_manager_webhook_tag - cluster_issuer_name = include.root.inputs.cluster_issuer_name -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-config/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-config/terragrunt.hcl deleted file mode 100644 index d4a60dbc..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-config/terragrunt.hcl +++ /dev/null @@ -1,42 +0,0 @@ -# lab/development/us-gov-east-1/vpc/platform-eng-eks-mcm/eks-config/terragrunt.hcl - -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -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=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_certificate_authority_data = [{ data = "THISISAVERYLONGCERTSTRINGTHATGOESHEREFORSURENODYEP" }] - cluster_endpoint = "https://12345ABCDEE42BF9C24D4C362D1DC.sk1.us-gov-east-1.eks.amazonaws.com" - cluster_name = "a-cluster-name" - eks_managed_node_groups_autoscaling_group_names = ["eks-eks-a-cluster-name-node_group-0000000000000000000000000-5ac8a5e3-14dd-c043-2cc9-f4b6ffb36d32"] - oidc_provider_arn = "arn:aws-us-gov:iam::111111111111:oidc-provider/oidc.eks.us-gov-east-1.amazonaws.com/id/0000000000000000AAAAAAAAAAAAAAAA" - security_group_all_worker_mgmt_id = "sg-00b0000000000000" - subnets = ["subnet-00000000000000001", "subnet-00000000000000002", "subnet-00000000000000003"] - token = [{ token = "THISISTHETOKENTHATDOESNTEXISTTHEREAREMANYLIKEITBUTHISONEISFORACLUSTER" }] - vpc_id = "a-vpc-id" - } -} - -inputs = { - profile = include.root.inputs.aws_profile - region = include.root.inputs.aws_region - vpc_id = dependency.eks.outputs.vpc_id - cluster_name = dependency.eks.outputs.cluster_name - subnets = dependency.eks.outputs.subnets - security_group_all_worker_mgmt_id = dependency.eks.outputs.security_group_all_worker_mgmt_id - 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 - kubectl_image_tag = include.root.inputs.kubectl_image_tag -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-dns/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-dns/terragrunt.hcl deleted file mode 100644 index 6e28781b..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-dns/terragrunt.hcl +++ /dev/null @@ -1,42 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -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=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - subnets = ["subnet-abcdefgh", "subnet-12345678", "subnet-ab12cd34"] - } -} - -dependency "istio" { - config_path = "../eks-istio" - mock_outputs = { - istio_ingress_lb = { - dns_name = "a1111111111111111111111111111111-2bbbbbbbbbbbbbbb.elb.us-gov-east-1.amazonaws.com" - zone_id = "ZABC123456DEF" - } - } -} - -inputs = { - cluster_name = dependency.eks.inputs.cluster_name - istio_ingress_lb = dependency.istio.outputs.istio_ingress_lb - profile = include.root.inputs.aws_profile - region = include.root.inputs.aws_region - subnets = dependency.eks.outputs.subnets - tags = dependency.eks.inputs.tags - vpc_domain_name = dependency.eks.inputs.vpc_domain_name - vpc_name = dependency.eks.inputs.vpc_name - route53_endpoints = include.root.inputs.route53_endpoints -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-grafana/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-grafana/terragrunt.hcl deleted file mode 100644 index 65ab33fe..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-grafana/terragrunt.hcl +++ /dev/null @@ -1,40 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-grafana.git?ref=${include.root.inputs.release_version}" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_name = "a-cluster-name" - } -} - -dependency "eks-loki" { - config_path = "../eks-loki" - mock_outputs = { - rwo_storage_class = "gp3-encrypted" - } -} - -inputs = { - profile = include.root.inputs.aws_profile - region = include.root.inputs.aws_region - cluster_name = dependency.eks.outputs.cluster_name - cluster_domain = dependency.eks.inputs.vpc_domain_name - public_hostname = include.root.inputs.grafana_hostname - rwo_storage_class = dependency.eks-loki.outputs.rwo_storage_class - grafana_chart_version = include.root.inputs.grafana_chart_version - grafana_tag = include.root.inputs.grafana_tag - download_dashboards_image_tag = include.root.inputs.download_dashboards_image_tag - init_chown_data_image_tag = include.root.inputs.init_chown_data_image_tag -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-istio/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-istio/terragrunt.hcl deleted file mode 100644 index c7c22c81..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-istio/terragrunt.hcl +++ /dev/null @@ -1,32 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -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=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_name = "a-cluster-name" - } -} -dependency "eks-karpenter" { - config_path = "../eks-karpenter" - skip_outputs = true -} - -inputs = { - profile = include.root.inputs.aws_profile - region = include.root.inputs.aws_region - cluster_name = dependency.eks.outputs.cluster_name - istio_chart_version = include.root.inputs.istio_version - istio_version = include.root.inputs.istio_version -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-k8s-dashboard/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-k8s-dashboard/terragrunt.hcl deleted file mode 100644 index cd1961b6..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-k8s-dashboard/terragrunt.hcl +++ /dev/null @@ -1,36 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-k8s-dashboard.git?ref=${include.root.inputs.release_version}" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_name = "a-cluster-name" - vpc_domain_name = "example.com" - } -} - -dependency "eks-loki" { - config_path = "../eks-loki" - skip_outputs = true -} - -inputs = { - profile = include.root.inputs.aws_profile - region = include.root.inputs.aws_region - cluster_name = dependency.eks.outputs.cluster_name - cluster_domain = dependency.eks.inputs.vpc_domain_name - public_hostname = include.root.inputs.dashboard_hostname - k8s_dashboard_version = include.root.inputs.k8s_dashboard_version - # datasources = dependency.eks-loki.outputs.gateway_internal_endpoint -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-karpenter/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-karpenter/terragrunt.hcl deleted file mode 100644 index 6b1a862f..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-karpenter/terragrunt.hcl +++ /dev/null @@ -1,43 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -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=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_endpoint = "https://0000000000000000AAAAAAAAAAAAAAAA.sk1.us-gov-east-1.eks.amazonaws.com" - cluster_name = "a-cluster-name" - node_group_name = "node_group_a-cluster-name" - oidc_provider_arn = "arn:aws-us-gov:iam::111111111111:oidc-provider/oidc.eks.us-gov-east-1.amazonaws.com/id/0000000000000000AAAAAAAAAAAAAAAA" - vpc_id = "a-vpc-name" - } -} - -dependency "eks-config" { - config_path = "../eks-config" - skip_outputs = true -} - -inputs = { - profile = include.root.inputs.aws_profile - region = include.root.inputs.aws_region - cluster_endpoint = dependency.eks.outputs.cluster_endpoint - cluster_name = dependency.eks.outputs.cluster_name - karpenter_node_group_name = dependency.eks.outputs.node_group_name - oidc_provider_arn = dependency.eks.outputs.oidc_provider_arn - vpc_id = dependency.eks.outputs.vpc_id - karpenter_helm_chart = include.root.inputs.karpenter_helm_chart - karpenter_tag = include.root.inputs.karpenter_tag - kubectl_tag = include.root.inputs.kubectl_image_tag - -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-kiali/terragrunt.hcl.disable b/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-kiali/terragrunt.hcl.disable deleted file mode 100644 index 1e04fe0d..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-kiali/terragrunt.hcl.disable +++ /dev/null @@ -1,81 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-kiali.git?ref=${include.root.inputs.release_version}" - # source = "../../../../../../../tfmod-kiali" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_name = "a-cluster-name" - } -} -dependency "eks-cert-manager" { - config_path = "../eks-cert-manager" - mock_outputs = { - cluster_issuer_name = "acmpca-clusterissuer" - } -} -dependency "eks-prometheus" { - config_path = "../eks-prometheus" - mock_outputs = { - prometheus_server_internal_endpoint = { - hostname = "prometheus-server.prometheus.svc.cluster.local" - port_number = 9090 - url = "http://prometheus-server.prometheus.svc.cluster.local:9090/" - } - } -} -dependency "eks-grafana" { - config_path = "../eks-grafana" - mock_outputs = { - internal_endpoint = { - hostname = "grafana.grafana.svc.cluster.local" - port_number = "80" - url = "https://grafana.grafana.svc.cluster.local:80/" - } - namespace = "grafana" - public_endpoint = { - hostname = "grafana.dev.lab.csp2.census.gov" - port_number = "80" - url = "https://grafana.dev.lab.csp2.census.gov:80/" - } - secret_name = "grafana" - } -} - -inputs = { - kiali_operator_version = include.root.inputs.kiali_operator_version - kiali_application_version = include.root.inputs.kiali_application_version - - profile = include.root.inputs.aws_profile - cluster_domain = dependency.eks.inputs.vpc_domain_name - operators_namespace = "operators" - cluster_name = dependency.eks.outputs.cluster_name - certificate_issuer = dependency.eks-cert-manager.outputs.cluster_issuer_name - prometheus_internal_url = dependency.eks-prometheus.outputs.prometheus_server_internal_endpoint.url - grafana_internal_url = dependency.eks-grafana.outputs.internal_endpoint.url - grafana_namespace = dependency.eks-grafana.outputs.namespace - grafana_public_url = dependency.eks-grafana.outputs.public_endpoint.url - grafana_secret_name = "grafana" - # grafana_secret_name = dependency.eks-grafana.outputs.secret_name - jaeger_internal_url = "" - - - # client_id = var.sso_client_id - # client_secret = var.sso_client_secret - # keycloak_public_url = var.keycloak_public_url - # gogatekeeper_chart_version = var.gogatekeeper_chart_version - # gogatekeeper_registry = var.gogatekeeper_registry - # gogatekeeper_repository = var.gogatekeeper_repository - # gogatekeeper_tag = var.gogatekeeper_tag -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-loki/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-loki/terragrunt.hcl deleted file mode 100644 index 2c6b6be5..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-loki/terragrunt.hcl +++ /dev/null @@ -1,44 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-loki.git?ref=${include.root.inputs.release_version}" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_name = "a-cluster-name" - oidc_provider_arn = "arn:aws-us-gov:iam::111111111111:oidc-provider/oidc.eks.us-gov-east-1.amazonaws.com/id/0000000000000000AAAAAAAAAAAAAAAA" - } -} -dependency "eks-istio" { - config_path = "../eks-istio" - skip_outputs = true -} -dependency "eks-prometheus" { - config_path = "../eks-prometheus" - skip_outputs = true -} - -inputs = { - profile = include.root.inputs.aws_profile - region = include.root.inputs.aws_region - cluster_name = dependency.eks.outputs.cluster_name - oidc_provider_arn = dependency.eks.outputs.oidc_provider_arn - loki_chart_version = include.root.inputs.loki_chart_version - loki_tag = include.root.inputs.loki_tag - canary_tag = include.root.inputs.canary_tag - enterprise_logs_provisioner_tag = include.root.inputs.enterprise_logs_provisioner_tag - gateway_tag = include.root.inputs.gateway_tag - memcached_tag = include.root.inputs.memcached_tag - exporter_tag = include.root.inputs.exporter_tag - sidecar_tag = include.root.inputs.sidecar_tag -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-metrics-server/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-metrics-server/terragrunt.hcl deleted file mode 100644 index 387653b9..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-metrics-server/terragrunt.hcl +++ /dev/null @@ -1,33 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-metrics-server.git?ref=${include.root.inputs.release_version}" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_name = "a-cluster-name" - } -} - -dependency "eks_config" { - config_path = "../eks-config" - skip_outputs = true -} - -inputs = { - profile = include.root.inputs.aws_profile - cluster_name = dependency.eks.outputs.cluster_name - region = include.root.inputs.aws_region - metrics_server_helm_chart = include.root.inputs.metrics_server_helm_chart - metrics_server_tag = include.root.inputs.metrics_server_tag -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-prometheus/README.md b/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-prometheus/README.md deleted file mode 100644 index bbbffb2a..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-prometheus/README.md +++ /dev/null @@ -1,198 +0,0 @@ -## eks-prometheus -This module deploys EKS kubeenetes prometheus inside existing EKS cluster. Prometheus is an open-source systems monitoring and alerting tool. -This module consisits of 4 components. It creates prometheus namespace and copies image repositories for the following components from quay.io into local account ECR repository. It deploys these components using helm charts using the configured ECR repositories. - 1. prometheus-alert-manager - 2. prometheus-node-exporter - 3. prometheus-pushgateway - 4. prometheus-server - -### Dependencies -This module is dependent on EKS module (eks). The cluster should exist already for this module to work. - -### Inputs - cluster_name - profile - prometheus_chart_version - prometheus_server_tag - prometheus_config_reloader_tag - alertmanager_tag - kube_state_metrics_tag - node_exporter_tag - pushgateway_tag - rwo_storage_class - -### Outputs - alertmanager_internal_endpoint - alertmanager_headless_internal_endpoint - pushgateway_internal_endpoint - prometheus_server_internal_endpoint - -### Issues observed/fixed -1. The rwo_storage_class value had to be updated from "gp3" to "gp3-encrypted" -2. The node_exporter_tag value had to be updated from "1.6.1" to "v1.8.1" -3. The kube_state_metrics_tag value had to be updated from "2.10.0" to "v2.6.0" -4. The alertmanager_tag value had to be updated from -5. The helm chart set config for the ecr image had to be split into 2 components, one for registry and other for repository as an example mentioned below: - - ``` - set { - name = "kube-state-metrics.image.registry" - value = module.images.images[local.ksm_key].dest_registry - } - set { - name = "kube-state-metrics.image.repository" - value = module.images.images[local.ksm_key].dest_repository - } - ``` - -6. In some other cases the image ecr repository had to be split by the colon separatory (:) - - ``` - set { - name = "alertmanager.configmapReload.image.repository" - value = split(":", module.images.images[local.prom_config_reload_key].dest_full_path)[0] - } - ``` - -### Chart Notes - 1. Get the application URL by running these commands: - - ```bash - export POD_NAME=$(kubectl get pods --namespace prometheus -l "app.kubernetes.io/name=prometheus-pushgateway,app.kubernetes.io/instance=prometheus" -o jsonpath="{.items[0].metadata.name}") - kubectl port-forward $POD_NAME 9091 - echo "Visit http://127.0.0.1:9091 to use your application" - ``` - - The Prometheus server can be accessed via port 80 on the following DNS name from within your cluster: - prometheus-server.prometheus.svc.cluster.local - - - Get the Prometheus server URL by running these commands in the same shell: - - ```bash - export POD_NAME=$(kubectl get pods --namespace prometheus -l "app.kubernetes.io/name=prometheus,app.kubernetes.io/instance=prometheus" -o jsonpath="{.items[0].metadata.name}") - kubectl --namespace prometheus port-forward $POD_NAME 9090 - ``` - - The Prometheus alertmanager can be accessed via port 9093 on the following DNS name from within your cluster: - `prometheus-alertmanager.prometheus.svc.cluster.local` - - - Get the Alertmanager URL by running these commands in the same shell: - - ```bash - export POD_NAME=$(kubectl get pods --namespace prometheus -l "app.kubernetes.io/name=alertmanager,app.kubernetes.io/instance=prometheus" -o jsonpath="{.items[0].metadata.name}") - kubectl --namespace prometheus port-forward $POD_NAME 9093 - ``` - - ################################################################################# - ###### WARNING: Pod Security Policy has been disabled by default since ##### - ###### it deprecated after k8s 1.25+. use ##### - ###### (index .Values "prometheus-node-exporter" "rbac" ##### - ###### "pspEnabled") with (index .Values ##### - ###### "prometheus-node-exporter" "rbac" "pspAnnotations") ##### - ###### in case you still need it. ##### - ################################################################################# - - - The Prometheus PushGateway can be accessed via port 9091 on the following DNS name from within your cluster: - `prometheus-prometheus-pushgateway.prometheus.svc.cluster.local` - - - Get the PushGateway URL by running these commands in the same shell: - - ```bash - export POD_NAME=$(kubectl get pods --namespace prometheus -l "app=prometheus-pushgateway,component=pushgateway" -o jsonpath="{.items[0].metadata.name}") - kubectl --namespace prometheus port-forward $POD_NAME 9091 - ``` - - For more information on running Prometheus, visit: - https://prometheus.io/ - - kube-state-metrics is a simple service that listens to the Kubernetes API server and generates metrics about the state of the objects. - The exposed metrics can be found here: - https://github.com/kubernetes/kube-state-metrics/blob/master/docs/README.md#exposed-metrics - - The metrics are exported on the HTTP endpoint /metrics on the listening port. - In your case, `prometheus-kube-state-metrics.prometheus.svc.cluster.local:8080/metrics` - - They are served either as plaintext or protobuf depending on the Accept header. - They are designed to be consumed either by Prometheus itself or by a scraper that is compatible with scraping a Prometheus client endpoint. - - 1. Get the application URL by running these commands: - - ```bash - export POD_NAME=$(kubectl get pods --namespace prometheus -l "app.kubernetes.io/name=alertmanager,app.kubernetes.io/instance=prometheus" -o jsonpath="{.items[0].metadata.name}") - echo "Visit http://127.0.0.1:9093 to use your application" - kubectl --namespace prometheus port-forward $POD_NAME 9093:80 - ``` - - 1. Get the application URL by running these commands: - - ```bash - export POD_NAME=$(kubectl get pods --namespace prometheus -l "app.kubernetes.io/name=prometheus-node-exporter,app.kubernetes.io/instance=prometheus" -o jsonpath="{.items[0].metadata.name}") - echo "Visit http://127.0.0.1:9100 to use your application" - kubectl port-forward --namespace prometheus $POD_NAME 9100 - ``` - - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 0.13 | -| [aws](#requirement\_aws) | >= 5.14.0 | -| [helm](#requirement\_helm) | >= 2.11.0 | -| [kubernetes](#requirement\_kubernetes) | >= 2.23.0 | -| [null](#requirement\_null) | >= 3.2.1 | - -## Providers - -| Name | Version | -|------|---------| -| [helm](#provider\_helm) | >= 2.11.0 | -| [kubernetes](#provider\_kubernetes) | >= 2.23.0 | - -## Modules - -| Name | Source | Version | -|------|--------|---------| -| [images](#module\_images) | git@github.e.it.census.gov:terraform-modules/aws-ecr-copy-images.git/ | tf-upgrade | - -## Resources - -| Name | Type | -|------|------| -| [helm_release.prometheus](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | -| [kubernetes_namespace.ns](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) | resource | -| [kubernetes_namespace.existing-ns](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/data-sources/namespace) | data source | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [alertmanager\_tag](#input\_alertmanager\_tag) | The image tag of the alertmanager image. | `string` | `"v0.27.0"` | no | -| [cluster\_name](#input\_cluster\_name) | The name of the cluster into which prometheus will be installed. | `string` | n/a | yes | -| [create\_namespace](#input\_create\_namespace) | Indicates whether the `namespace` needs to be created ('true') or already exists (not `true`) | `bool` | `true` | no | -| [kube\_state\_metrics\_tag](#input\_kube\_state\_metrics\_tag) | The image tag of the kube-state-metrics image. | `string` | `"v2.13.0"` | no | -| [namespace](#input\_namespace) | The namespace to install the prometheus components. Defaults to 'prometheus' | `string` | `"prometheus"` | no | -| [node\_exporter\_tag](#input\_node\_exporter\_tag) | The image tag of the node-exporter image. | `string` | `"v1.8.2"` | no | -| [profile](#input\_profile) | AWS\_PROFILE to use to apply the terraform script. | `string` | `""` | no | -| [prometheus\_chart\_version](#input\_prometheus\_chart\_version) | The version of prometheus to install into the cluster. | `string` | `"25.24.1"` | no | -| [prometheus\_config\_reloader\_tag](#input\_prometheus\_config\_reloader\_tag) | The image tag of the prometheus-config-reloader image. | `string` | `"v0.75.1"` | no | -| [prometheus\_server\_tag](#input\_prometheus\_server\_tag) | The image tag of prometheus server to install into the cluster. | `string` | `"v2.53.1"` | no | -| [pushgateway\_tag](#input\_pushgateway\_tag) | The image tag of the pushgateway image. | `string` | `"v1.9.0"` | no | -| [rwo\_storage\_class](#input\_rwo\_storage\_class) | Specify the storage class for read/write/once persistent volumes. | `string` | `"gp3-encrypted"` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| [alertmanager\_headless\_internal\_endpoint](#output\_alertmanager\_headless\_internal\_endpoint) | n/a | -| [alertmanager\_internal\_endpoint](#output\_alertmanager\_internal\_endpoint) | n/a | -| [module\_name](#output\_module\_name) | The name of this module. | -| [module\_version](#output\_module\_version) | The version of this module. | -| [prometheus\_namespace](#output\_prometheus\_namespace) | n/a | -| [prometheus\_server\_internal\_endpoint](#output\_prometheus\_server\_internal\_endpoint) | n/a | -| [pushgateway\_internal\_endpoint](#output\_pushgateway\_internal\_endpoint) | n/a | - diff --git a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-prometheus/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-prometheus/terragrunt.hcl deleted file mode 100644 index e6c54b16..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-prometheus/terragrunt.hcl +++ /dev/null @@ -1,38 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-prometheus.git?ref=${include.root.inputs.release_version}" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_name = "a-cluster-name" - } -} - -dependency "eks-dns" { - config_path = "../eks-dns" - skip_outputs = true -} - -inputs = { - profile = include.root.inputs.aws_profile - region = include.root.inputs.aws_region - cluster_name = dependency.eks.outputs.cluster_name - prometheus_chart_version = include.root.inputs.prometheus_chart_version - prometheus_server_tag = include.root.inputs.prometheus_server_tag - prometheus_config_reloader_tag = include.root.inputs.prometheus_config_reloader_tag - alertmanager_tag = include.root.inputs.alertmanager_tag - kube_state_metrics_tag = include.root.inputs.kube_state_metrics_tag - node_exporter_tag = include.root.inputs.node_exporter_tag - pushgateway_tag = include.root.inputs.pushgateway_tag -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-tempo/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-tempo/terragrunt.hcl deleted file mode 100644 index e9ebd485..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks-tempo/terragrunt.hcl +++ /dev/null @@ -1,46 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-tempo.git?ref=${include.root.inputs.release_version}" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_name = "a-cluster-name" - oidc_provider_arn = "arn:aws-us-gov:iam::111111111111:oidc-provider/oidc.eks.us-gov-east-1.amazonaws.com/id/0000000000000000AAAAAAAAAAAAAAAA" - } -} - -dependency "eks-prometheus" { - config_path = "../eks-prometheus" - mock_outputs = { - prometheus_server_internal_endpoint = { - hostname = "prometheus-server.prometheus.svc.cluster.local" - port_number = 9090 - url = "http://prometheus-server.prometheus.svc.cluster.local:9090/" - } - prometheus_namespace = "prometheus" - } -} - -inputs = { - account_id = include.root.locals.account_id - profile = include.root.locals.aws_profile - region = include.root.locals.aws_region - cluster_name = dependency.eks.outputs.cluster_name - oidc_provider_arn = dependency.eks.outputs.oidc_provider_arn - prometheus_port = dependency.eks-prometheus.outputs.prometheus_server_internal_endpoint.port_number - prometheus_namespace = dependency.eks-prometheus.outputs.prometheus_namespace - tempo_chart_version = include.root.inputs.tempo_chart_version - tempo_tag = include.root.inputs.tempo_tag - -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks/terragrunt.hcl deleted file mode 100644 index cc7c8935..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-cicd/eks/terragrunt.hcl +++ /dev/null @@ -1,56 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -locals { - # Set cluster/platform specific variables, or extract from the hierarchy. - account_id = include.root.inputs.aws_account_id - cluster_endpoint_public_access = include.root.inputs.cluster_endpoint_public_access - cluster_name = include.root.inputs.cluster_name - cluster_version = include.root.inputs.cluster_version - creator = include.root.inputs.creator - eks_instance_disk_size = include.root.inputs.eks_instance_disk_size - 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_vpc_name = include.root.inputs.vpc_name - enable_cluster_creator_admin_permissions = include.root.inputs.enable_cluster_creator_admin_permissions - environment_abbr = include.root.inputs.environment_abbr - organization = include.root.inputs.organization - profile = include.root.inputs.aws_profile - project_name = include.root.inputs.project_name - project_number = include.root.inputs.project_number - project_role = include.root.inputs.project_role - region = include.root.inputs.aws_region - tags = include.root.inputs.tags - terraform = include.root.inputs.terraform - terragrunt = include.root.inputs.terragrunt - vpc_domain_name = include.root.inputs.vpc_domain_name -} - -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=20m"] - } -} - -inputs = { - aws_account_id = local.account_id - cluster_endpoint_public_access = local.cluster_endpoint_public_access - cluster_name = local.cluster_name - cluster_version = local.cluster_version - creator = local.creator - eks_instance_disk_size = local.eks_instance_disk_size - eks_ng_desired_size = local.eks_ng_desired_size - eks_ng_max_size = local.eks_ng_max_size - eks_ng_min_size = local.eks_ng_min_size - eks_vpc_name = local.eks_vpc_name - enable_cluster_creator_admin_permissions = local.enable_cluster_creator_admin_permissions - os_username = local.creator - shared_vpc_label = local.environment_abbr - tags = local.tags -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-x/cluster.hcl b/lab/development/us-gov-east-1/vpc/platform-test-x/cluster.hcl deleted file mode 100644 index 8d2831cf..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-x/cluster.hcl +++ /dev/null @@ -1,20 +0,0 @@ -# lab/development/us-gov-east-1/vpc/platform-eng-eks-mcm/cluster.hcl - -# Set cluster specific variables. These are automatically pulled in to configure the remote state bucket in the root -# terragrunt.hcl configuration. -locals { - cluster_endpoint_public_access = true - cluster_name = "platform-eng-eks-mcm" - creator = "matthew.c.morgan@census.gov" - eks_instance_disk_size = 100 - eks_ng_desired_size = 2 - eks_ng_max_size = 10 - eks_ng_min_size = 0 - enable_cluster_creator_admin_permissions = true - terraform = true - terragrunt = true - tags = { - "slim:schedule" = "8:00-17:00" - "cluster:size" = "min:${local.eks_ng_min_size}-max:${local.eks_ng_max_size}-desired:${local.eks_ng_desired_size}" - } -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-z/cluster.hcl b/lab/development/us-gov-east-1/vpc/platform-test-z/cluster.hcl deleted file mode 100644 index 740c1ad9..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-z/cluster.hcl +++ /dev/null @@ -1,21 +0,0 @@ -# lab/development/us-gov-east-1/vpc/platform-eng-eks-mcm/cluster.hcl - -# Set cluster specific variables. These are automatically pulled in to configure the remote state bucket in the root -# terragrunt.hcl configuration. -locals { - cluster_endpoint_public_access = true - cluster_name = "platform-test-z" - created_reason = "Terragrunt Development for CICD Delivered EKS Platform" - creator = "luther.coleman.mcginty@census.gov" - eks_instance_disk_size = 100 - eks_ng_desired_size = 3 - eks_ng_max_size = 10 - eks_ng_min_size = 1 - enable_cluster_creator_admin_permissions = true - terraform = true - terragrunt = true - tags = { - "slim:schedule" = "8:00-17:00" - "cluster:size" = "min:${local.eks_ng_min_size}-max:${local.eks_ng_max_size}-desired:${local.eks_ng_desired_size}" - } -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-alloy-disable/terragrunt.hcl.disable b/lab/development/us-gov-east-1/vpc/platform-test-z/eks-alloy-disable/terragrunt.hcl.disable deleted file mode 100644 index 97aa66fd..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-alloy-disable/terragrunt.hcl.disable +++ /dev/null @@ -1,27 +0,0 @@ -include "root" { - path = find_in_parent_folders() - expose = true -} - -terraform { - # source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-alloy.git?ref=main" - source = "../../../../../../../tfmod-alloy" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_name = "a-cluster-name" - } -} - -inputs = { - profile = include.root.inputs.aws_profile - cluster_name = dependency.eks.outputs.cluster_name - region = include.root.inputs.aws_region - cluster_domain = dependency.eks.inputs.vpc_domain_name -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-cert-manager/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-z/eks-cert-manager/terragrunt.hcl deleted file mode 100644 index 2522e07a..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-cert-manager/terragrunt.hcl +++ /dev/null @@ -1,57 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - # source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-cert-mgr.git?ref=${include.root.inputs.release_version}" - source = "../../../../../../../tfmod-cert-mgr" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependencies { - paths = [ - "../eks", - "../eks-config", - "../eks-karpenter" - ] -} - -dependency "eks" { - config_path = "../eks" - mock_outputs_allowed_terraform_commands = ["init", "plan", "validate", "destroy"] - - mock_outputs = { - cluster_name = include.root.inputs.cluster_name - oidc_provider_arn = "arn:aws-us-gov:iam::123456789012:oidc-provider/mock" - cluster_endpoint = "https://mock-endpoint.eks.amazonaws.com" - cluster_version = include.root.inputs.cluster_version - } -} - -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 = dependency.eks.outputs.cluster_name - cluster_mailing_list = include.root.inputs.cluster_mailing_list - oidc_provider_arn = dependency.eks.outputs.oidc_provider_arn - - # Cert Manager Configuration - cert_manager_helm_chart = include.root.inputs.cert_manager_helm_chart - cluster_issuer_name = include.root.inputs.cluster_issuer_name - - # Version Tags - cert_manager_cainjector_tag = include.root.inputs.cert_manager_cainjector_tag - cert_manager_controller_tag = include.root.inputs.cert_manager_controller_tag - cert_manager_startupapicheck_tag = include.root.inputs.cert_manager_startupapicheck_tag - cert_manager_webhook_tag = include.root.inputs.cert_manager_webhook_tag - namespace = include.root.inputs.namespaces["cert-manager"] -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-config/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-z/eks-config/terragrunt.hcl deleted file mode 100644 index eefbf272..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-config/terragrunt.hcl +++ /dev/null @@ -1,54 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -dependencies { - paths = [ - "../eks", - # "../eks-karpenter" - ] -} - -terraform { - # source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-eks-configuration.git?ref=${include.root.inputs.release_version}" - source = "../../../../../../../tfmod-eks-configuration" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -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" - } -} - -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/development/us-gov-east-1/vpc/platform-test-z/eks-dns/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-z/eks-dns/terragrunt.hcl deleted file mode 100644 index 83eb25fb..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-dns/terragrunt.hcl +++ /dev/null @@ -1,61 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - # source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-eks-dns.git?ref=${include.root.inputs.release_version}" - source = "../../../../../../../tfmod-eks-dns" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -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-config", - "../eks-istio", - "../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 - - # Cluster Configuration - cluster_name = include.root.inputs.cluster_name - - # 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/development/us-gov-east-1/vpc/platform-test-z/eks-grafana/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-z/eks-grafana/terragrunt.hcl deleted file mode 100644 index dda8453f..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-grafana/terragrunt.hcl +++ /dev/null @@ -1,81 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - # source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-grafana.git?ref=${include.root.inputs.release_version}" - source = "../../../../../../../tfmod-grafana" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependencies { - paths = [ - "../eks", - "../eks-loki", - "../eks-prometheus", - "../eks-tempo" - ] -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_name = "a-cluster-name" - } -} - -dependency "eks-loki" { - config_path = "../eks-loki" - mock_outputs = { - rwo_storage_class = "gp3-encrypted" - gateway_internal_endpoint = { - hostname = "loki-gateway.telemetry.svc.cluster.local" - portNumber = "80" - url = "http://loki-gateway.telemetry.svc.cluster.local:80/" - } - } -} - -dependency "eks-prometheus" { - config_path = "../eks-prometheus" - mock_outputs = { - prometheus_server_internal_endpoint = { - hostname = "prometheus-server.prometheus.svc.cluster.local" - port_number = 9090 - url = "http://prometheus-server.prometheus.svc.cluster.local:9090/" - } - } -} - -dependency "eks-tempo" { - config_path = "../eks-tempo" - mock_outputs = { - tempo_internal_endpoint = { - hostname = "tempo.telemetry.svc.cluster.local" - port_number = 4317 - url = "http://tempo.telemetry.svc.cluster.local:4317/" - } - } -} - -inputs = { - cluster_domain = dependency.eks.inputs.vpc_domain_name - cluster_name = dependency.eks.outputs.cluster_name - download_dashboards_image_tag = include.root.inputs.download_dashboards_image_tag - grafana_chart_version = include.root.inputs.grafana_chart_version - grafana_tag = include.root.inputs.grafana_tag - init_chown_data_image_tag = include.root.inputs.init_chown_data_image_tag - profile = include.root.inputs.aws_profile - public_hostname = include.root.inputs.grafana_hostname - region = include.root.inputs.aws_region - rwo_storage_class = dependency.eks-loki.outputs.rwo_storage_class - loki_endpoint = dependency.eks-loki.outputs.gateway_internal_endpoint.url - prometheus_endpoint = dependency.eks-prometheus.outputs.prometheus_server_internal_endpoint.url - tempo_endpoint = dependency.eks-tempo.outputs.tempo_internal_endpoint.url - namespace = include.root.inputs.namespaces["grafana"] -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-istio/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-z/eks-istio/terragrunt.hcl deleted file mode 100644 index dff8a76c..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-istio/terragrunt.hcl +++ /dev/null @@ -1,45 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - # source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-istio.git?ref=${include.root.inputs.release_version}" - source = "../../../../../../../tfmod-istio" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependencies { - paths = [ - "../eks", - "../eks-config" - ] -} - -dependency "eks" { - config_path = "../eks" - mock_outputs_allowed_terraform_commands = ["init", "plan", "validate", "destroy"] - mock_outputs = { - cluster_name = include.root.inputs.cluster_name - oidc_provider_arn = "arn:aws-us-gov:iam::123456789012:oidc-provider/mock" - } -} - -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 = dependency.eks.outputs.cluster_name - oidc_provider_arn = dependency.eks.outputs.oidc_provider_arn - - # Istio Configuration - namespace = include.root.inputs.namespaces["istio"] - istio_version = include.root.inputs.istio_version -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-k8s-dashboard/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-z/eks-k8s-dashboard/terragrunt.hcl deleted file mode 100644 index 7bccdc3f..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-k8s-dashboard/terragrunt.hcl +++ /dev/null @@ -1,46 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - # source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-k8s-dashboard.git?ref=${include.root.inputs.release_version}" - source = "../../../../../../../tfmod-k8s-dashboard" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependencies { - paths = [ - "../eks", - "../eks-config", - "../eks-dns" - ] -} - -dependency "eks" { - config_path = "../eks" - mock_outputs_allowed_terraform_commands = ["init", "plan", "validate", "destroy"] - mock_outputs = { - cluster_name = include.root.inputs.cluster_name - oidc_provider_arn = "arn:aws-us-gov:iam::123456789012:oidc-provider/mock" - } -} - -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_domain = include.root.inputs.vpc_domain_name - cluster_name = dependency.eks.outputs.cluster_name - - # Dashboard Configuration - k8s_dashboard_version = include.root.inputs.k8s_dashboard_version - namespace = include.root.inputs.namespaces["k8s-dashboard"] -} \ No newline at end of file diff --git a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-karpenter/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-z/eks-karpenter/terragrunt.hcl deleted file mode 100644 index a713f4d9..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-karpenter/terragrunt.hcl +++ /dev/null @@ -1,49 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - # source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-karpenter.git?ref=${include.root.inputs.release_version}" - source = "../../../../../../../tfmod-karpenter" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} -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 - - # 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 - - # 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"] -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-kiali/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-z/eks-kiali/terragrunt.hcl deleted file mode 100644 index d0494ec1..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-kiali/terragrunt.hcl +++ /dev/null @@ -1,91 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - # source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-kiali.git?ref=mcmCluster" - source = "../../../../../../../tfmod-kiali" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_name = "a-cluster-name" - } -} -dependency "eks-cert-manager" { - config_path = "../eks-cert-manager" - mock_outputs = { - cluster_issuer_name = "acmpca-clusterissuer" - } -} -dependency "eks-prometheus" { - config_path = "../eks-prometheus" - mock_outputs = { - prometheus_server_internal_endpoint = { - hostname = "prometheus-server.prometheus.svc.cluster.local" - port_number = 9090 - url = "http://prometheus-server.prometheus.svc.cluster.local:9090/" - } - } -} -dependency "eks-tempo" { - config_path = "../eks-tempo" - mock_outputs = { - tempo_internal_endpoint = { - hostname = "tempo.tempo.svc.cluster.local" - port_number = 3100 - url = "http://tempo.tempo.svc.cluster.local:3100/" - } - } -} -dependency "eks-grafana" { - config_path = "../eks-grafana" - mock_outputs = { - internal_endpoint = { - hostname = "grafana.grafana.svc.cluster.local" - port_number = "80" - url = "https://grafana.grafana.svc.cluster.local:80/" - } - namespace = "grafana" - public_endpoint = "https://grafana.dev.lab.csp2.census.gov:80/" - secret_name = "grafana" - tempo_datasource_id = "tempo" - } -} - -inputs = { - profile = include.root.inputs.aws_profile - cluster_domain = dependency.eks.inputs.vpc_domain_name - cluster_name = dependency.eks.outputs.cluster_name - certificate_issuer = dependency.eks-cert-manager.outputs.cluster_issuer_name - - kiali_application_version = include.root.inputs.kiali_application_version - - namespace = include.root.inputs.namespaces["kiali"] - istio_namespace = include.root.inputs.namespaces["istio"] - - prometheus_internal_url = dependency.eks-prometheus.outputs.prometheus_server_internal_endpoint.url - grafana_namespace = dependency.eks-grafana.outputs.namespace - grafana_secret_name = dependency.eks-grafana.outputs.secret_name - grafana_internal_url = dependency.eks-grafana.outputs.internal_endpoint.url - grafana_public_url = dependency.eks-grafana.outputs.public_endpoint - tempo_datasource_id = dependency.eks-grafana.outputs.tempo_datasource_id - tempo_internal_url = dependency.eks-tempo.outputs.tempo_internal_endpoint.url - - - - # client_id = var.sso_client_id - # client_secret = var.sso_client_secret - # keycloak_public_url = var.keycloak_public_url - # gogatekeeper_chart_version = var.gogatekeeper_chart_version - # gogatekeeper_registry = var.gogatekeeper_registry - # gogatekeeper_repository = var.gogatekeeper_repository - # gogatekeeper_tag = var.gogatekeeper_tag -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-loki/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-z/eks-loki/terragrunt.hcl deleted file mode 100644 index 4c4de2fd..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-loki/terragrunt.hcl +++ /dev/null @@ -1,48 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - # source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-loki.git?ref=${include.root.inputs.release_version}" - source = "../../../../../../../tfmod-loki-x" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_name = "a-cluster-name" - oidc_provider_arn = "arn:aws-us-gov:iam::111111111111:oidc-provider/oidc.eks.us-gov-east-1.amazonaws.com/id/0000000000000000AAAAAAAAAAAAAAAA" - } -} - -dependency "eks-istio" { - config_path = "../eks-istio" - skip_outputs = true -} - -# dependency "eks-prometheus" { -# config_path = "../eks-prometheus" -# skip_outputs = true -# } - -inputs = { - profile = include.root.inputs.aws_profile - region = include.root.inputs.aws_region - cluster_name = dependency.eks.outputs.cluster_name - oidc_provider_arn = dependency.eks.outputs.oidc_provider_arn - loki_chart_version = include.root.inputs.loki_chart_version - loki_tag = include.root.inputs.loki_tag - canary_tag = include.root.inputs.canary_tag - enterprise_logs_provisioner_tag = include.root.inputs.enterprise_logs_provisioner_tag - gateway_tag = include.root.inputs.gateway_tag - memcached_tag = include.root.inputs.memcached_tag - exporter_tag = include.root.inputs.exporter_tag - sidecar_tag = include.root.inputs.sidecar_tag - namespace = include.root.inputs.namespaces["loki"] -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-metrics-server/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-z/eks-metrics-server/terragrunt.hcl deleted file mode 100644 index 06817cc0..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-metrics-server/terragrunt.hcl +++ /dev/null @@ -1,44 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -dependencies { - paths = [ - "../eks", - "../eks-config" - ] -} - -terraform { - # source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-metrics-server.git?ref=${include.root.inputs.release_version}" - source = "../../../../../../../tfmod-metrics-server" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs_allowed_terraform_commands = ["init", "plan", "validate", "destroy"] - mock_outputs = { - cluster_name = "mock-cluster" - } -} - -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 = dependency.eks.outputs.cluster_name - - # Metrics Server Configuration - metrics_server_helm_chart = include.root.inputs.metrics_server_helm_chart - metrics_server_tag = include.root.inputs.metrics_server_tag - namespace = include.root.inputs.namespaces["metrics-server"] -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-open-telemetry/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-z/eks-open-telemetry/terragrunt.hcl deleted file mode 100644 index 2b4ce337..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-open-telemetry/terragrunt.hcl +++ /dev/null @@ -1,61 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - # source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-open-telemetry.git?ref=main" - source = "../../../../../../../tfmod-open-telemetry" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependencies { - paths = [ - "../eks", - "../eks-loki", - "../eks-prometheus", - "../eks-tempo" - ] -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_name = "a-cluster-name" - } -} - -dependency "eks-loki" { - config_path = "../eks-loki" - mock_outputs = { - gateway_internal_endpoint = { - hostname = "loki-gateway.telemetry.svc.cluster.local" - portNumber = "80" - url = "http://loki-gateway.telemetry.svc.cluster.local:80/" - } - } -} - -dependency "eks-tempo" { - config_path = "../eks-tempo" - mock_outputs = { - tempo_otlp_endpoint = { - hostname = "tempo.telemetry.svc.cluster.local" - portNumber = 4317 - url = "http://tempo.telemetry.svc.cluster.local:4317/" - } - } -} - -inputs = { - profile = include.root.inputs.aws_profile - cluster_name = dependency.eks.outputs.cluster_name - region = include.root.inputs.aws_region - namespace = include.root.inputs.namespaces["otel"] - loki_endpoint = dependency.eks-loki.outputs.gateway_internal_endpoint.url - tempo_endpoint = dependency.eks-tempo.outputs.tempo_otlp_endpoint.url -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-prometheus/README.md b/lab/development/us-gov-east-1/vpc/platform-test-z/eks-prometheus/README.md deleted file mode 100644 index bbbffb2a..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-prometheus/README.md +++ /dev/null @@ -1,198 +0,0 @@ -## eks-prometheus -This module deploys EKS kubeenetes prometheus inside existing EKS cluster. Prometheus is an open-source systems monitoring and alerting tool. -This module consisits of 4 components. It creates prometheus namespace and copies image repositories for the following components from quay.io into local account ECR repository. It deploys these components using helm charts using the configured ECR repositories. - 1. prometheus-alert-manager - 2. prometheus-node-exporter - 3. prometheus-pushgateway - 4. prometheus-server - -### Dependencies -This module is dependent on EKS module (eks). The cluster should exist already for this module to work. - -### Inputs - cluster_name - profile - prometheus_chart_version - prometheus_server_tag - prometheus_config_reloader_tag - alertmanager_tag - kube_state_metrics_tag - node_exporter_tag - pushgateway_tag - rwo_storage_class - -### Outputs - alertmanager_internal_endpoint - alertmanager_headless_internal_endpoint - pushgateway_internal_endpoint - prometheus_server_internal_endpoint - -### Issues observed/fixed -1. The rwo_storage_class value had to be updated from "gp3" to "gp3-encrypted" -2. The node_exporter_tag value had to be updated from "1.6.1" to "v1.8.1" -3. The kube_state_metrics_tag value had to be updated from "2.10.0" to "v2.6.0" -4. The alertmanager_tag value had to be updated from -5. The helm chart set config for the ecr image had to be split into 2 components, one for registry and other for repository as an example mentioned below: - - ``` - set { - name = "kube-state-metrics.image.registry" - value = module.images.images[local.ksm_key].dest_registry - } - set { - name = "kube-state-metrics.image.repository" - value = module.images.images[local.ksm_key].dest_repository - } - ``` - -6. In some other cases the image ecr repository had to be split by the colon separatory (:) - - ``` - set { - name = "alertmanager.configmapReload.image.repository" - value = split(":", module.images.images[local.prom_config_reload_key].dest_full_path)[0] - } - ``` - -### Chart Notes - 1. Get the application URL by running these commands: - - ```bash - export POD_NAME=$(kubectl get pods --namespace prometheus -l "app.kubernetes.io/name=prometheus-pushgateway,app.kubernetes.io/instance=prometheus" -o jsonpath="{.items[0].metadata.name}") - kubectl port-forward $POD_NAME 9091 - echo "Visit http://127.0.0.1:9091 to use your application" - ``` - - The Prometheus server can be accessed via port 80 on the following DNS name from within your cluster: - prometheus-server.prometheus.svc.cluster.local - - - Get the Prometheus server URL by running these commands in the same shell: - - ```bash - export POD_NAME=$(kubectl get pods --namespace prometheus -l "app.kubernetes.io/name=prometheus,app.kubernetes.io/instance=prometheus" -o jsonpath="{.items[0].metadata.name}") - kubectl --namespace prometheus port-forward $POD_NAME 9090 - ``` - - The Prometheus alertmanager can be accessed via port 9093 on the following DNS name from within your cluster: - `prometheus-alertmanager.prometheus.svc.cluster.local` - - - Get the Alertmanager URL by running these commands in the same shell: - - ```bash - export POD_NAME=$(kubectl get pods --namespace prometheus -l "app.kubernetes.io/name=alertmanager,app.kubernetes.io/instance=prometheus" -o jsonpath="{.items[0].metadata.name}") - kubectl --namespace prometheus port-forward $POD_NAME 9093 - ``` - - ################################################################################# - ###### WARNING: Pod Security Policy has been disabled by default since ##### - ###### it deprecated after k8s 1.25+. use ##### - ###### (index .Values "prometheus-node-exporter" "rbac" ##### - ###### "pspEnabled") with (index .Values ##### - ###### "prometheus-node-exporter" "rbac" "pspAnnotations") ##### - ###### in case you still need it. ##### - ################################################################################# - - - The Prometheus PushGateway can be accessed via port 9091 on the following DNS name from within your cluster: - `prometheus-prometheus-pushgateway.prometheus.svc.cluster.local` - - - Get the PushGateway URL by running these commands in the same shell: - - ```bash - export POD_NAME=$(kubectl get pods --namespace prometheus -l "app=prometheus-pushgateway,component=pushgateway" -o jsonpath="{.items[0].metadata.name}") - kubectl --namespace prometheus port-forward $POD_NAME 9091 - ``` - - For more information on running Prometheus, visit: - https://prometheus.io/ - - kube-state-metrics is a simple service that listens to the Kubernetes API server and generates metrics about the state of the objects. - The exposed metrics can be found here: - https://github.com/kubernetes/kube-state-metrics/blob/master/docs/README.md#exposed-metrics - - The metrics are exported on the HTTP endpoint /metrics on the listening port. - In your case, `prometheus-kube-state-metrics.prometheus.svc.cluster.local:8080/metrics` - - They are served either as plaintext or protobuf depending on the Accept header. - They are designed to be consumed either by Prometheus itself or by a scraper that is compatible with scraping a Prometheus client endpoint. - - 1. Get the application URL by running these commands: - - ```bash - export POD_NAME=$(kubectl get pods --namespace prometheus -l "app.kubernetes.io/name=alertmanager,app.kubernetes.io/instance=prometheus" -o jsonpath="{.items[0].metadata.name}") - echo "Visit http://127.0.0.1:9093 to use your application" - kubectl --namespace prometheus port-forward $POD_NAME 9093:80 - ``` - - 1. Get the application URL by running these commands: - - ```bash - export POD_NAME=$(kubectl get pods --namespace prometheus -l "app.kubernetes.io/name=prometheus-node-exporter,app.kubernetes.io/instance=prometheus" -o jsonpath="{.items[0].metadata.name}") - echo "Visit http://127.0.0.1:9100 to use your application" - kubectl port-forward --namespace prometheus $POD_NAME 9100 - ``` - - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 0.13 | -| [aws](#requirement\_aws) | >= 5.14.0 | -| [helm](#requirement\_helm) | >= 2.11.0 | -| [kubernetes](#requirement\_kubernetes) | >= 2.23.0 | -| [null](#requirement\_null) | >= 3.2.1 | - -## Providers - -| Name | Version | -|------|---------| -| [helm](#provider\_helm) | >= 2.11.0 | -| [kubernetes](#provider\_kubernetes) | >= 2.23.0 | - -## Modules - -| Name | Source | Version | -|------|--------|---------| -| [images](#module\_images) | git@github.e.it.census.gov:terraform-modules/aws-ecr-copy-images.git/ | tf-upgrade | - -## Resources - -| Name | Type | -|------|------| -| [helm_release.prometheus](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | -| [kubernetes_namespace.ns](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) | resource | -| [kubernetes_namespace.existing-ns](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/data-sources/namespace) | data source | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [alertmanager\_tag](#input\_alertmanager\_tag) | The image tag of the alertmanager image. | `string` | `"v0.27.0"` | no | -| [cluster\_name](#input\_cluster\_name) | The name of the cluster into which prometheus will be installed. | `string` | n/a | yes | -| [create\_namespace](#input\_create\_namespace) | Indicates whether the `namespace` needs to be created ('true') or already exists (not `true`) | `bool` | `true` | no | -| [kube\_state\_metrics\_tag](#input\_kube\_state\_metrics\_tag) | The image tag of the kube-state-metrics image. | `string` | `"v2.13.0"` | no | -| [namespace](#input\_namespace) | The namespace to install the prometheus components. Defaults to 'prometheus' | `string` | `"prometheus"` | no | -| [node\_exporter\_tag](#input\_node\_exporter\_tag) | The image tag of the node-exporter image. | `string` | `"v1.8.2"` | no | -| [profile](#input\_profile) | AWS\_PROFILE to use to apply the terraform script. | `string` | `""` | no | -| [prometheus\_chart\_version](#input\_prometheus\_chart\_version) | The version of prometheus to install into the cluster. | `string` | `"25.24.1"` | no | -| [prometheus\_config\_reloader\_tag](#input\_prometheus\_config\_reloader\_tag) | The image tag of the prometheus-config-reloader image. | `string` | `"v0.75.1"` | no | -| [prometheus\_server\_tag](#input\_prometheus\_server\_tag) | The image tag of prometheus server to install into the cluster. | `string` | `"v2.53.1"` | no | -| [pushgateway\_tag](#input\_pushgateway\_tag) | The image tag of the pushgateway image. | `string` | `"v1.9.0"` | no | -| [rwo\_storage\_class](#input\_rwo\_storage\_class) | Specify the storage class for read/write/once persistent volumes. | `string` | `"gp3-encrypted"` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| [alertmanager\_headless\_internal\_endpoint](#output\_alertmanager\_headless\_internal\_endpoint) | n/a | -| [alertmanager\_internal\_endpoint](#output\_alertmanager\_internal\_endpoint) | n/a | -| [module\_name](#output\_module\_name) | The name of this module. | -| [module\_version](#output\_module\_version) | The version of this module. | -| [prometheus\_namespace](#output\_prometheus\_namespace) | n/a | -| [prometheus\_server\_internal\_endpoint](#output\_prometheus\_server\_internal\_endpoint) | n/a | -| [pushgateway\_internal\_endpoint](#output\_pushgateway\_internal\_endpoint) | n/a | - diff --git a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-prometheus/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-z/eks-prometheus/terragrunt.hcl deleted file mode 100644 index 030dd33c..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-prometheus/terragrunt.hcl +++ /dev/null @@ -1,40 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - # source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-prometheus.git?ref=${include.root.inputs.release_version}" - source = "../../../../../../../tfmod-prometheus" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_name = "a-cluster-name" - } -} - -dependency "eks-dns" { - config_path = "../eks-dns" - skip_outputs = true -} - -inputs = { - profile = include.root.inputs.aws_profile - region = include.root.inputs.aws_region - cluster_name = dependency.eks.outputs.cluster_name - prometheus_chart_version = include.root.inputs.prometheus_chart_version - prometheus_server_tag = include.root.inputs.prometheus_server_tag - prometheus_config_reloader_tag = include.root.inputs.prometheus_config_reloader_tag - alertmanager_tag = include.root.inputs.alertmanager_tag - kube_state_metrics_tag = include.root.inputs.kube_state_metrics_tag - node_exporter_tag = include.root.inputs.node_exporter_tag - pushgateway_tag = include.root.inputs.pushgateway_tag - namespace = include.root.inputs.namespaces["prometheus"] -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-tempo/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-z/eks-tempo/terragrunt.hcl deleted file mode 100644 index d14c8a1e..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-z/eks-tempo/terragrunt.hcl +++ /dev/null @@ -1,47 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - # source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-tempo.git?ref=${include.root.inputs.release_version}" - source = "../../../../../../../tfmod-tempo" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -dependency "eks" { - config_path = "../eks" - mock_outputs = { - cluster_name = "a-cluster-name" - oidc_provider_arn = "arn:aws-us-gov:iam::111111111111:oidc-provider/oidc.eks.us-gov-east-1.amazonaws.com/id/0000000000000000AAAAAAAAAAAAAAAA" - } -} - -dependency "eks-prometheus" { - config_path = "../eks-prometheus" - mock_outputs = { - prometheus_server_internal_endpoint = { - hostname = "prometheus-server.prometheus.svc.cluster.local" - port_number = 9090 - url = "http://prometheus-server.prometheus.svc.cluster.local:9090/" - } - prometheus_namespace = "prometheus" - } -} - -inputs = { - account_id = include.root.locals.account_id - profile = include.root.locals.aws_profile - region = include.root.locals.aws_region - cluster_name = dependency.eks.outputs.cluster_name - oidc_provider_arn = dependency.eks.outputs.oidc_provider_arn - prometheus_port = dependency.eks-prometheus.outputs.prometheus_server_internal_endpoint.port_number - prometheus_namespace = dependency.eks-prometheus.outputs.prometheus_namespace - tempo_chart_version = include.root.inputs.tempo_chart_version - tempo_tag = include.root.inputs.tempo_tag - namespace = include.root.inputs.namespaces["tempo"] -} diff --git a/lab/development/us-gov-east-1/vpc/platform-test-z/eks/terragrunt.hcl b/lab/development/us-gov-east-1/vpc/platform-test-z/eks/terragrunt.hcl deleted file mode 100644 index c77be43b..00000000 --- a/lab/development/us-gov-east-1/vpc/platform-test-z/eks/terragrunt.hcl +++ /dev/null @@ -1,28 +0,0 @@ -include "root" { - path = find_in_parent_folders("root.hcl") - merge_strategy = "deep" - expose = true -} - -terraform { - # source = "git@github.e.it.census.gov:SCT-Engineering/tfmod-eks.git?ref=${include.root.inputs.release_version}" - source = "../../../../../../../tfmod-eks" - extra_arguments "retry_lock" { - commands = get_terraform_commands_that_need_locking() - arguments = ["-lock-timeout=20m"] - } -} - -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 - - # Additional Configuration - tags = include.root.inputs.tags -} diff --git a/lab/root.hcl b/lab/root.hcl index 10706ffd..b0666374 100644 --- a/lab/root.hcl +++ b/lab/root.hcl @@ -15,6 +15,9 @@ locals { # 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")) @@ -24,21 +27,36 @@ locals { # 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 - aws_profile = local.account_vars.locals.aws_profile - aws_region = local.region_vars.locals.aws_region - cluster_name = local.cluster_vars.locals.cluster_name - environment_abbr = local.account_vars.locals.environment_abbr - organization = local.common_vars.locals.organization - project_name = local.common_vars.locals.project_name - project_number = local.common_vars.locals.project_number - project_role = local.common_vars.locals.project_role + 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.account_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" + 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 - # Check if current module is the EKS module - module_name = basename(get_original_terragrunt_dir()) - is_eks_module = local.module_name == "eks" } # Only generate providers for non-EKS modules @@ -82,7 +100,7 @@ generate "helm_provider" { if_exists = "overwrite_terragrunt" contents = local.is_eks_module ? "" : <<-EOF provider "helm" { - kubernetes { + 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" @@ -94,24 +112,19 @@ generate "helm_provider" { # Configure Terragrunt to automatically store tfstate files in an S3 bucket remote_state { - backend = "s3" + 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}" - dynamodb_table = "${local.state_table_name}" - 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 - skip_bucket_enforced_tls = true # use only if you need to access the S3 bucket without TLS being enforced - skip_bucket_public_access_blocking = true - skip_bucket_root_access = true # use only if the AWS account root user should not have access to the remote state bucket for some reason - skip_bucket_ssencryption = true # use only if non-encrypted OpenTofu/Terraform State is required and/or the object store does not support server-side encryption - skip_bucket_versioning = false # use only if the object store does not support versioning - enable_lock_table_ssencryption = false # use only if non-encrypted DynamoDB Lock Table for the OpenTofu/Terraform State is required and/or the NoSQL database service does not support server-side encryption + 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 } } @@ -128,9 +141,9 @@ generate "aws-provider" { cluster_name = "${local.cluster_name}" "boc:module_name" = "${local.module_name}" environment = "${local.environment_abbr}" - finops_project_name = "${local.project_name}" - finops_project_number = "${local.project_number}" - finops_project_role = "${local.project_role}" + finops_project_name = "${local.finops_project_name}" + finops_project_number = "${local.finops_project_number}" + finops_project_role = "${local.finops_project_role}" organization = "${local.organization}" } } @@ -152,7 +165,9 @@ 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.vpc_vars.locals, + local.root_locals_for_inputs ) diff --git a/notes.md b/notes.md deleted file mode 100644 index 55a5ffc3..00000000 --- a/notes.md +++ /dev/null @@ -1,78 +0,0 @@ -I really like these suggestions, but I want to help shape your suggestions with some prime directives for these tasks: -1. security is paramount. we operate in govcloud and handle titled data. security is the most important consideration. -2. cost control - this is a base cluster for a customer to build on top of for their apps. It is anticipated there will be significant time between initial provisioning and first use. The cheapest possible configuration for secure operations in govcloud. -3. simplicity. ideally, I want to be able to add a single file to an exising git repository (which represents an aws account), and have it spawn this entire cluster definition. -4. maintainability. As in, a minimum amount of effort to maintain,, prioritizing future-proofing in decisions. -5. extensibility. try to keep things modular and able to be glued together as easy as possible. -6. best practices. should probably be higher in this list, but at all times, we should endevour to follow/encourage best practices. -7. testability. we are dealing with eks clusters in aws here. by nature, these are expensive resources. anything we can do to test without creation of resources, or rapid creation and destruction, is encouraged. -8. documentation - including the 5 W's (who, what, when, where, why, and how) - -Given those guidelines, does that change your suggestions? Should we start the code review over with those in mind? - -Improvement: Consider adding validation blocks for required variables -Improvement: Add more detailed comments explaining configuration choices -Improvement: Consider tagging strategy for cost allocation -Improvement: Add lifecycle policies for node groups -Warning: Public endpoint access enabled - consider restricting CIDR ranges -Improvement: Add explicit IAM role configurations -Improvement: Implement network policies -# Add to cluster configuration -cluster_security_group_additional_rules = { - ingress_nodes_ephemeral_ports = { - description = "Node to node ephemeral ports" - protocol = "tcp" - from_port = 1025 - to_port = 65535 - type = "ingress" - source_node_security_group = true - } -} -Add CloudWatch logging configuration -Implement proper metrics collection -Set up alerts for cluster health -Improvement: Add more detailed documentation -Improvement: Consider adding test environments -Add README files in each major directory -Document deployment procedures -Add troubleshooting guides -Document network architecture - -resource "aws_eks_cluster" "main" { - # ...existing code... - vpc_config { - endpoint_private_access = true - endpoint_public_access = false # Force private endpoint only - security_group_ids = [aws_security_group.cluster.id] - subnet_ids = var.private_subnet_ids - } - - encryption_config { - provider { - key_arn = aws_kms_key.eks.arn - } - resources = ["secrets"] - } -} - -24m Warning FailedGetResourceMetric horizontalpodautoscaler/loki-write failed to get cpu utilization: unable to get metrics for resource cpu: no metrics returned from resource metrics API -24m Warning FailedComputeMetricsReplicas horizontalpodautoscaler/loki-write invalid metrics (1 invalid out of 1), first error is: failed to get cpu resource metric value: failed to get cpu utilization: unable to get metrics for resource cpu: no metrics returned from resource metrics API -22m Warning FailedGetResourceMetric horizontalpodautoscaler/loki-write failed to get cpu utilization: did not receive metrics for targeted pods (pods might be unready) -2 -29m Warning FailedGetResourceMetric horizontalpodautoscaler/istiod failed to get cpu utilization: unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server could not find the requested resource (get pods.metrics.k8s.io) -29m Warning FailedComputeMetricsReplicas horizontalpodautoscaler/istiod invalid metrics (1 invalid out of 1), first error is: failed to get cpu resource metric value: failed to get cpu utilization: unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server could not find the requested resource (get pods.metrics.k8s.io) -29m Warning FailedGetResourceMetric horizontalpodautoscaler/istiod failed to get cpu utilization: unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server is currently unable to handle the request (get pods.metrics.k8s.io) -29m Warning FailedComputeMetricsReplicas horizontalpodautoscaler/istiod invalid metrics (1 invalid out of 1), first error is: failed to get cpu resource metric value: failed to get cpu utilization: unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server is currently unable to handle the request (get pods.metrics.k8s.io) -2 -* Failed to execute "terraform_current apply -lock-timeout=20m -auto-approve -input=false -auto-approve" in ./.terragrunt-cache/jrM5TqaHxjlphT8vQ1DicmFp6eM/1NbRS_ankC8AcxKegXNWAnjyQEg - ╷ - │ Error: Unable to continue with install: Certificate "platform-eng-eks-mcm" in namespace "istio-system" exists and cannot be imported into the current release: invalid ownership metadata; annotation validation error: key "meta.helm.sh/release-name" must equal "grafana-grafana-ingress": current value is "k8s-dashboard-k8s-dashboard-ingress"; annotation validation error: key "meta.helm.sh/release-namespace" must equal "grafana": current value is "k8s-dashboard" - │ - │ with module.ingress_resources.helm_release.ingress, - │ on .terraform/modules/ingress_resources/main.tf line 6, in resource "helm_release" "ingress": - │ 6: resource "helm_release" "ingress" { - │ - ╵ - - exit status 1 - \ No newline at end of file diff --git a/plan.md b/plan.md deleted file mode 100644 index bd058fd3..00000000 --- a/plan.md +++ /dev/null @@ -1,271 +0,0 @@ -Project Plan: EKS Infrastructure Codebase Improvements -1. Documentation Standardization - - Create centralized documentation standards guide - - Implement standardized README structure across all modules: - * Overview and purpose - * Prerequisites and dependencies - * Usage examples with variables - * Architecture diagrams - * Operations guide - - Establish changelog format using Commitizen convention - - Create architecture diagrams: - * High-level system architecture - * Module relationships - * Network flow diagrams - * Security group configurations - - Develop consistent module examples: - * Basic usage patterns - * Advanced configurations - * Migration guides - * Troubleshooting guides - - Implementation timeline: - * Week 1: Standards guide creation - * Week 2-3: README updates - * Week 4: Diagram creation - * Week 5: Example development - * Week 6: Review and refinement - -2. Security Enhancements - - EKS Security Group Configurations: - * Implement least-privilege access rules - * Restrict node group communication - * Define approved ingress/egress patterns - * Document security group dependencies - - - AWS GovCloud Security Implementation: - * Enable FIPS 140-2 compliant endpoints - * Implement NIST 800-53 controls - * Configure AWS KMS for all sensitive data - * Enable AWS Organizations SCPs - - - Encryption Configurations: - * Enable envelope encryption for secrets - * Implement at-rest encryption for EBS volumes - * Configure TLS for all service communications - * Rotate encryption keys automatically - - - Network Security Policies: - * Define default deny policies - * Create application-specific network policies - * Implement pod security policies - * Configure service mesh security - - - Implementation Timeline: - * Week 1: Security audit and gap analysis - * Week 2: Security group updates - * Week 3: Encryption improvements - * Week 4: Network policy implementation - * Week 5: Testing and validation - * Week 6: Documentation and training - -3. Observability Improvements - - Prometheus Configuration Standardization: - * Define standard metric collection rules - * Implement consistent recording rules - * Set up unified alerting rules - * Configure HA architecture - - - Metrics Collection Strategy: - * Define golden signals metrics - * Implement custom metric collectors - * Set up SLO/SLI tracking - * Configure cost metrics collection - - - Logging Framework: - * Implement structured logging - * Configure log aggregation - * Set up log retention policies - * Enable audit logging - - - Grafana Dashboards: - * Create cluster health dashboards - * Implement cost monitoring views - * Set up performance dashboards - * Configure security monitoring panels - - - Implementation Timeline: - * Week 1: Metrics standardization - * Week 2: Logging implementation - * Week 3: Dashboard creation - * Week 4: Alert configuration - * Week 5: Testing and validation - * Week 6: Documentation and training - -4. Infrastructure Optimization - - Node Group Configuration: - * Implement right-sized instance types - * Configure optimal scaling thresholds - * Set up mixed-instance policies - * Define node taints and labels - - - Auto-scaling Strategy: - * Configure Cluster Autoscaler settings - * Implement Karpenter provisioners - * Set up pod disruption budgets - * Define scaling policies - - - Storage Optimization: - * Define storage class specifications - * Implement volume encryption - * Configure backup policies - * Set up snapshot schedules - - - Resource Management: - * Implement namespace quotas - * Define limit ranges - * Configure resource requests/limits - * Set up cost allocation tags - - - Implementation Timeline: - * Week 1: Node group optimization - * Week 2: Auto-scaling implementation - * Week 3: Storage configuration - * Week 4: Resource quotas setup - * Week 5: Testing and validation - * Week 6: Documentation and training - -5. Module Organization - - Module Standardization: - * Create consistent module structure - * Implement standard naming conventions - * Define input/output patterns - * Establish version constraints - - - Variable Management: - * Create shared variable definitions - * Implement variable validation rules - * Define default value standards - * Document variable dependencies - - - Version Control: - * Implement semantic versioning - * Create version compatibility matrix - * Define upgrade paths - * Document breaking changes - - - Dependencies: - * Map module relationships - * Document cross-module dependencies - * Define initialization order - * Create dependency graphs - - - Implementation Timeline: - * Week 1: Module structure standardization - * Week 2: Variable management - * Week 3: Version control implementation - * Week 4: Dependency documentation - * Week 5: Testing and validation - * Week 6: Documentation and training - -6. Testing Framework - - Terraform Validation: - * Implement pre-commit hooks - * Configure format checking - * Add variable validation - * Set up static analysis - - - Integration Testing: - * Create test environments - * Implement end-to-end tests - * Configure smoke tests - * Set up regression testing - - - Security Testing: - * Implement security scanners - * Configure compliance checks - * Add vulnerability scanning - * Set up secret detection - - - Test Automation: - * Configure CI/CD pipelines - * Implement test reporting - * Set up coverage tracking - * Create automated rollbacks - - - Implementation Timeline: - * Week 1: Validation framework setup - * Week 2: Integration test development - * Week 3: Security scanning implementation - * Week 4: Automation configuration - * Week 5: Testing and validation - * Week 6: Documentation and training - -Implementation Priority: - - Security Enhancements (Critical) - - Observability Improvements (High) - - Infrastructure Optimization (High) - - Documentation Standardization (Medium) - - Module Organization (Medium) - - Testing Framework (Medium) - -Key Metrics: - - Security compliance score - - Resource utilization efficiency - - Documentation coverage - - Test coverage - - Code duplication reduction - - Deployment success rate - -Next Steps: - -1. Security Audit (Week 1-2) - - Perform comprehensive security assessment - * Review IAM roles and permissions - * Audit security group configurations - * Analyze network policies - * Review encryption settings - - Generate security findings report - - Prioritize security improvements - - Create remediation timeline - -2. Implementation Planning (Week 2-3) - - Create detailed project timeline - * Break down tasks by module - * Identify dependencies - * Assign ownership - * Set milestones - - Establish success criteria - - Define rollback procedures - - Create risk mitigation strategies - -3. Testing Pipeline Setup (Week 3-4) - - Configure CI/CD infrastructure - * Set up test environments - * Implement automated testing - * Configure quality gates - * Enable security scanning - - Create test data sets - - Develop test scenarios - - Implement monitoring for test environments - -4. Documentation Enhancement (Week 4-5) - - Audit existing documentation - - Create documentation templates - - Update README files - - Generate architecture diagrams - - Create operational runbooks - - Document emergency procedures - -5. Module Consolidation (Week 5-6) - - Analyze current module structure - - Identify consolidation opportunities - - Create module dependency map - - Plan refactoring phases - - Document migration steps - - Create validation checklist - -6. Validation and Review (Week 6-7) - - Conduct peer reviews - - Perform security validation - - Test documentation accuracy - - Validate monitoring setup - - Review automation effectiveness - - Gather stakeholder feedback - -7. Training and Handover (Week 7-8) - - Prepare training materials - - Schedule training sessions - - Document operational procedures - - Create troubleshooting guides - - Set up support channels - - Plan knowledge transfer sessions