From ce9c5037645d04345310e6cecb48bdaa44ab38b5 Mon Sep 17 00:00:00 2001 From: arnol377 Date: Fri, 4 Apr 2025 19:15:23 -0400 Subject: [PATCH] Add comprehensive EKS Cluster Template roadmap and configuration files --- ROADMAP.md | 59 ++++++++++ locals.tf | 144 ++++++++++++++++++++++++ main.tf | 28 +++++ templates/common-variables.hcl | 10 ++ templates/default-versions.hcl | 124 +++++++++++++++++++++ variables.tf | 194 +++++++++++++++++++++++++++++++++ versions.tf | 7 ++ 7 files changed, 566 insertions(+) create mode 100644 ROADMAP.md create mode 100644 locals.tf create mode 100644 main.tf create mode 100644 templates/common-variables.hcl create mode 100644 templates/default-versions.hcl create mode 100644 variables.tf create mode 100644 versions.tf diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..f7160db --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,59 @@ +# EKS Cluster Template Roadmap + +## Current Architecture +- Template repository (`template-eks-cluster`) serves as the base for creating new EKS cluster configurations +- Uses Terraform GitHub repo module to create new repositories from the template +- Implements managed and non-managed extra files functionality +- Supports configuration through `config.json` + +## Planned Enhancements + +### 1. Automated Cluster Setup (High Priority) +- [ ] Add GitHub Actions workflows with workflow_dispatch triggers +- [ ] Implement automated terragrunt command execution for cluster building +- [ ] Configure workflows to run on specific runners for credential management +- [ ] Create templatized GitHub Actions workflow files +- [ ] Enable direct cluster creation without manual repository cloning + +### 2. File Management System (Medium Priority) +- [ ] Implement wrapper module for repo module +- [ ] Add support for crafting and injecting various configuration files +- [ ] Define file lifecycle management strategy + - [ ] Managed files (controlled by workspace) + - [ ] Non-managed files (user-modifiable) + +### 3. Version Management (Medium Priority) +- [ ] Implement version control strategy for `default-versions.hcl` +- [ ] Create system for managing platform release versions +- [ ] Set up version override mechanism + - [ ] Default versions in template repo + - [ ] Override capability in workspace creating repos + +### 4. Configuration Management (Low Priority) +- [ ] Enhance Makefile and Ansible playbook integration +- [ ] Improve configuration file templating +- [ ] Add validation for configuration files + +## Technical Considerations +1. File Lifecycle Management: + - Managed files: Controlled by workspace + - Non-managed files: User-modifiable post-creation + - Version-specific files: Platform release coordination + +2. Automation Requirements: + - GitHub Actions runner configuration + - Credential management + - Workflow templating + - Terragrunt integration + +3. Version Control Strategy: + - Module version collections + - Platform release versions + - Override mechanisms + +## Success Criteria +- Fully automated cluster creation process +- Minimal manual intervention required +- Proper version management system +- Clear file lifecycle management +- Secure credential handling \ No newline at end of file diff --git a/locals.tf b/locals.tf new file mode 100644 index 0000000..acf38af --- /dev/null +++ b/locals.tf @@ -0,0 +1,144 @@ +locals { + common_vars = merge({ + organization = "census:ocio:csvd" + project_name = "csvd_platformbaseline" + project_number = "fs0000000078" + project_role = "csvd_platformbaseline_app" + state_bucket_prefix = "inf-tfstate" + state_table_name = "tf_remote_state" + route53_endpoints = {} + }, var.common_variables) + + all_namespaces = merge({ + grafana = local.namespaces.telemetry_namespace + k8s-dashboard = local.namespaces.telemetry_namespace + loki = local.namespaces.telemetry_namespace + otel = local.namespaces.telemetry_namespace + prometheus = local.namespaces.telemetry_namespace + tempo = local.namespaces.telemetry_namespace + }, var.namespaces.custom_namespaces) + + namespaces = { + operator_namespace = var.namespaces.operator_namespace + telemetry_namespace = var.namespaces.telemetry_namespace + namespaces = local.all_namespaces + } + + default_versions = { + cluster_version = var.versions.cluster_version + custom_service_eks_account = var.versions.release_version + eks_module_version = var.versions.eks_module_version + istio_ingress_version = var.versions.release_version + release_version = var.versions.release_version + + # Provider versions + aws_version = var.versions.aws_version + helm_version = var.versions.helm_version + kubernetes_version = var.versions.kubernetes_version + null_version = var.versions.null_version + random_version = var.versions.random_version + template_version = var.versions.template_version + tf_version = var.versions.tf_version + + # Component versions + cert_manager_version = var.versions.cert_manager.version + cert_manager_helm_chart = var.versions.cert_manager.chart_version + cluster_issuer_name = var.versions.cert_manager.cluster_issuer_name + + gogatekeeper_tag = var.versions.gogatekeeper.tag + gogatekeeper_chart_version = var.versions.gogatekeeper.chart_version + + grafana_hostname = var.versions.grafana.hostname + grafana_operator_chart_version = var.versions.grafana.operator_chart_version + grafana_operator_tag = var.versions.grafana.operator_tag + grafana_tag = var.versions.grafana.tag + os_shell_image_tag = var.versions.grafana.os_shell_image_tag + + istio_version = var.versions.istio.version + istio_namespace = var.versions.istio.namespace + + dashboard_hostname = var.versions.k8s_dashboard.hostname + k8s_dashboard_metrics_scraper = var.versions.k8s_dashboard.metrics_scraper + k8s_dashboard_version = var.versions.k8s_dashboard.version + + karpenter_helm_chart = var.versions.karpenter.helm_chart + karpenter_tag = var.versions.karpenter.tag + + keycloak_chart_version = var.versions.keycloak.chart_version + keycloak_tag = var.versions.keycloak.tag + keycloak_hostname = var.versions.keycloak.hostname + keycloak_database = var.versions.keycloak.database + keycloak_username = var.versions.keycloak.username + keycloak_password = var.versions.keycloak.password + postgresql_tag = var.versions.keycloak.postgresql_tag + + kiali_operator_version = var.versions.kiali.operator_version + kiali_application_version = "v${var.versions.kiali.operator_version}" + + loki_chart_version = var.versions.loki.chart_version + loki_tag = var.versions.loki.tag + enterprise_logs_provisioner_tag = var.versions.loki.enterprise_logs_provisioner_tag + gateway_tag = var.versions.loki.gateway_tag + memcached_tag = var.versions.loki.memcached_tag + exporter_tag = var.versions.loki.exporter_tag + sidecar_tag = var.versions.loki.sidecar_tag + + metrics_server_helm_chart = var.versions.metrics_server.helm_chart + metrics_server_tag = var.versions.metrics_server.tag + + prometheus_chart_version = var.versions.prometheus.chart_version + prometheus_server_tag = var.versions.prometheus.server_tag + prometheus_config_reloader_tag = var.versions.prometheus.config_reloader_tag + alertmanager_tag = var.versions.prometheus.alertmanager_tag + kube_state_metrics_tag = var.versions.prometheus.kube_state_metrics_tag + node_exporter_tag = var.versions.prometheus.node_exporter_tag + pushgateway_tag = var.versions.prometheus.pushgateway_tag + + tempo_chart_version = var.versions.tempo.chart_version + tempo_tag = var.versions.tempo.tag + } + + config_json = jsonencode({ + environment = var.environment + region = var.region + cluster_dir = "platform-cluster" + enable_all_modules = false + account = { + account_name = var.cluster_config.account_name + aws_account_id = var.cluster_config.aws_account_id + aws_profile = var.cluster_config.aws_profile + environment_abbr = var.cluster_config.environment_abbr + } + vpc = { + vpc_name = var.cluster_config.vpc_name + vpc_domain_name = var.cluster_config.vpc_domain_name + } + cluster = { + cluster_name = var.cluster_config.cluster_name + cluster_mailing_list = var.cluster_config.cluster_mailing_list + eks_instance_disk_size = var.cluster_config.eks_instance_disk_size + eks_ng_desired_size = var.cluster_config.eks_ng_desired_size + eks_ng_max_size = var.cluster_config.eks_ng_max_size + eks_ng_min_size = var.cluster_config.eks_ng_min_size + enable_cluster_creator_admin_permissions = var.cluster_config.enable_cluster_creator_admin_permissions + tags = var.cluster_config.tags + } + modules = var.enable_modules + }) + + managed_extra_files = concat([ + { + path = "config.json" + content = local.config_json + }, + { + path = "_envcommon/default-versions.hcl" + content = templatefile("${path.module}/templates/default-versions.hcl", local.default_versions) + }, + { + path = "_envcommon/common-variables.hcl" + content = templatefile("${path.module}/templates/common-variables.hcl", local.common_vars) + } + ], + var.github_actions_workflows) +} \ No newline at end of file diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..380a7c6 --- /dev/null +++ b/main.tf @@ -0,0 +1,28 @@ +module "github_repo" { + source = "HappyPathway/repo/github" + + name = var.name + repo_org = var.organization + github_repo_description = "EKS Cluster Configuration for ${var.cluster_config.cluster_name}" + github_repo_topics = ["eks", "kubernetes", "terraform", "infrastructure"] + + template_repo = "template-eks-cluster" + template_repo_org = var.template_repo_org + + github_is_private = true + github_has_issues = true + github_has_wiki = true + github_has_projects = true + + managed_extra_files = local.managed_extra_files +} + +output "repository_url" { + description = "URL of the created repository" + value = module.github_repo.html_url +} + +output "ssh_clone_url" { + description = "SSH clone URL of the repository" + value = module.github_repo.ssh_clone_url +} \ No newline at end of file diff --git a/templates/common-variables.hcl b/templates/common-variables.hcl new file mode 100644 index 0000000..e228659 --- /dev/null +++ b/templates/common-variables.hcl @@ -0,0 +1,10 @@ +locals { + organization = "${organization}" + project_name = "${project_name}" + project_number = "${project_number}" + project_role = "${project_role}" + state_bucket_prefix = "${state_bucket_prefix}" + state_table_name = "${state_table_name}" + + route53_endpoints = ${jsonencode(route53_endpoints)} +} \ No newline at end of file diff --git a/templates/default-versions.hcl b/templates/default-versions.hcl new file mode 100644 index 0000000..60f3cd4 --- /dev/null +++ b/templates/default-versions.hcl @@ -0,0 +1,124 @@ +locals { + ##################### + # Module Versions + ##################### + cluster_version = "${cluster_version}" + custom_service_eks_account = "${custom_service_eks_account}" + eks_module_version = "${eks_module_version}" + istio_ingress_version = "${istio_ingress_version}" + release_version = "${release_version}" + + ##################### + # TF Providers + ##################### + aws_version = "${aws_version}" + helm_version = "${helm_version}" + kubernetes_version = "${kubernetes_version}" + null_version = "${null_version}" + random_version = "${random_version}" + template_version = "${template_version}" + tf_version = "${tf_version}" + + ##################### + # Component Versions + ##################### + + ################ + # Cert-Manager + ################ + cluster_issuer_name = "${cluster_issuer_name}" + cert_manager_version = "${cert_manager_version}" + cert_manager_helm_chart = "${cert_manager_helm_chart}" + + ################ + # GoGatekeeper + ################ + gogatekeeper_tag = "${gogatekeeper_tag}" + gogatekeeper_chart_version = "${gogatekeeper_chart_version}" + + ################ + # Grafana + ################ + grafana_hostname = "${grafana_hostname}" + grafana_operator_chart_version = "${grafana_operator_chart_version}" + grafana_operator_tag = "${grafana_operator_tag}" + grafana_tag = "${grafana_tag}" + os_shell_image_tag = "${os_shell_image_tag}" + + ################ + # Istio + ################ + istio_namespace = "${istio_namespace}" + istio_version = "${istio_version}" + + ################ + # k8s-dashboard + ################ + dashboard_hostname = "${dashboard_hostname}" + k8s_dashboard_metrics_scraper = "${k8s_dashboard_metrics_scraper}" + k8s_dashboard_version = "${k8s_dashboard_version}" + + ################ + # Karpenter + ################ + karpenter_helm_chart = "${karpenter_helm_chart}" + karpenter_tag = "${karpenter_tag}" + + ################ + # Keycloak + ################ + keycloak_chart_version = "${keycloak_chart_version}" + keycloak_tag = "${keycloak_tag}" + keycloak_hostname = "${keycloak_hostname}" + keycloak_database = "${keycloak_database}" + keycloak_username = "${keycloak_username}" + keycloak_password = "${keycloak_password}" + postgresql_tag = "${postgresql_tag}" + + ################ + # Kiali + ################ + kiali_operator_version = "${kiali_operator_version}" + kiali_application_version = "${kiali_application_version}" + + ################ + # Loki + ################ + loki_chart_version = "${loki_chart_version}" + loki_tag = "${loki_tag}" + enterprise_logs_provisioner_tag = "${enterprise_logs_provisioner_tag}" + gateway_tag = "${gateway_tag}" + memcached_tag = "${memcached_tag}" + exporter_tag = "${exporter_tag}" + sidecar_tag = "${sidecar_tag}" + + ################ + # Metrics Server + ################ + metrics_server_helm_chart = "${metrics_server_helm_chart}" + metrics_server_tag = "${metrics_server_tag}" + + ################ + # Prometheus + ################ + prometheus_chart_version = "${prometheus_chart_version}" + prometheus_server_tag = "${prometheus_server_tag}" + prometheus_config_reloader_tag = "${prometheus_config_reloader_tag}" + alertmanager_tag = "${alertmanager_tag}" + kube_state_metrics_tag = "${kube_state_metrics_tag}" + node_exporter_tag = "${node_exporter_tag}" + pushgateway_tag = "${pushgateway_tag}" + + ################ + # Tempo + ################ + tempo_chart_version = "${tempo_chart_version}" + tempo_tag = "${tempo_tag}" + + ##################### + # Namespaces Config + ##################### + operator_namespace = "${operator_namespace}" + telemetry_namespace = "${telemetry_namespace}" + namespaces = ${jsonencode(namespaces)} +} \ No newline at end of file diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..fd4000d --- /dev/null +++ b/variables.tf @@ -0,0 +1,194 @@ +variable "name" { + description = "Name of the repository" + type = string +} + +variable "organization" { + description = "GitHub organization name" + type = string +} + +variable template_repo_org { + description = "GitHub organization for the template repository" + type = string +} + +variable "environment" { + description = "Environment name (e.g., production, staging)" + type = string +} + +variable "region" { + description = "AWS region for the EKS cluster" + type = string +} + +variable "common_variables" { + description = "Common variables across all environments" + type = object({ + organization = optional(string, "census:ocio:csvd") + project_name = optional(string, "csvd_platformbaseline") + project_number = optional(string, "fs0000000078") + project_role = optional(string, "csvd_platformbaseline_app") + state_bucket_prefix = optional(string, "inf-tfstate") + state_table_name = optional(string, "tf_remote_state") + route53_endpoints = optional(map(object({ + account_id = string + alias = string + us-gov-east-1 = string + us-gov-west-1 = string + })), {}) + }) + default = {} +} + +variable "versions" { + description = "Version configurations for various components" + type = object({ + # Module Versions + cluster_version = optional(string, "1.31") + eks_module_version = optional(string, "20.33.1") + release_version = optional(string, "main") + + # TF Providers + aws_version = optional(string, "5.84.0") + helm_version = optional(string, "2.11.0") + kubernetes_version = optional(string, "2.33.0") + null_version = optional(string, "3.2.1") + random_version = optional(string, "3.5.1") + template_version = optional(string, "2.2.0") + tf_version = optional(string, "1.5.5") + + # Component Versions + cert_manager = optional(object({ + version = optional(string, "1.17.1") + chart_version = optional(string, "1.17.1") + cluster_issuer_name = optional(string, "cert-manager") + }), {}) + + gogatekeeper = optional(object({ + tag = optional(string, "3.2.1") + chart_version = optional(string, "0.1.53") + }), {}) + + grafana = optional(object({ + hostname = optional(string, "grafana") + operator_chart_version = optional(string, "4.9.8") + operator_tag = optional(string, "5.16.0") + tag = optional(string, "11.5.2") + os_shell_image_tag = optional(string, "12") + }), {}) + + istio = optional(object({ + version = optional(string, "1.25.0") + namespace = optional(string, "istio-system") + }), {}) + + k8s_dashboard = optional(object({ + hostname = optional(string, "dashboard") + metrics_scraper = optional(string, "1.0.8") + version = optional(string, "6.0.6") + }), {}) + + karpenter = optional(object({ + helm_chart = optional(string, "1.3.1") + tag = optional(string, "1.3.1") + }), {}) + + keycloak = optional(object({ + chart_version = optional(string, "24.4.11") + tag = optional(string, "26.1.3") + hostname = optional(string, "keycloak") + database = optional(string, "keycloak") + username = optional(string, "keycloak") + password = optional(string, "this is my very secure and totally random password horse battery staple now") + postgresql_tag = optional(string, "17.4.0-debian-12-r2") + }), {}) + + kiali = optional(object({ + operator_version = optional(string, "2.2.0") + }), {}) + + loki = optional(object({ + chart_version = optional(string, "6.27.0") + tag = optional(string, "3.4.2") + enterprise_logs_provisioner_tag = optional(string, "v1.7.0") + gateway_tag = optional(string, "1.27-alpine") + memcached_tag = optional(string, "1.6.37") + exporter_tag = optional(string, "v0.15.0") + sidecar_tag = optional(string, "1.27.4") + }), {}) + + metrics_server = optional(object({ + helm_chart = optional(string, "3.12.2") + tag = optional(string, "0.7.2") + }), {}) + + prometheus = optional(object({ + chart_version = optional(string, "27.5.1") + server_tag = optional(string, "v3.2.1") + config_reloader_tag = optional(string, "v0.75.2") + alertmanager_tag = optional(string, "v0.28.0") + kube_state_metrics_tag = optional(string, "v2.15.0") + node_exporter_tag = optional(string, "v1.9.0") + pushgateway_tag = optional(string, "v1.11.0") + }), {}) + + tempo = optional(object({ + chart_version = optional(string, "1.18.2") + tag = optional(string, "2.7.1") + }), {}) + }) + default = {} +} + +variable "namespaces" { + description = "Namespace configurations" + type = object({ + operator_namespace = optional(string, "aoperator") + telemetry_namespace = optional(string, "atelemetry") + custom_namespaces = optional(map(string), { + cert-manager = "kube-system" + karpenter = "karpenter" + metrics-server = "kube-system" + postgresql = "kube-system" + keycloak = "keycloak" + gogatekeeper = "kube-system" + istio = "istio-system" + kiali = "istio-system" + }) + }) + default = {} +} + +variable "cluster_config" { + description = "Configuration for the EKS cluster" + type = object({ + cluster_name = string + account_name = string + aws_account_id = string + aws_profile = string + environment_abbr = string + vpc_name = string + vpc_domain_name = string + cluster_mailing_list = optional(string) + eks_instance_disk_size = optional(number, 200) + eks_ng_desired_size = optional(number, 3) + eks_ng_max_size = optional(number, 10) + eks_ng_min_size = optional(number, 3) + enable_cluster_creator_admin_permissions = optional(bool, true) + tags = optional(map(string), {}) + }) +} + +variable "enable_modules" { + description = "Map of modules to enable" + type = object({ + gogatekeeper = optional(bool, false) + cert_manager = optional(bool, false) + prometheus = optional(bool, false) + grafana = optional(bool, false) + istio = optional(bool, false) + }) + default = {} +} \ No newline at end of file diff --git a/versions.tf b/versions.tf new file mode 100644 index 0000000..fbe53be --- /dev/null +++ b/versions.tf @@ -0,0 +1,7 @@ +terraform { + required_providers { + github = { + source = "integrations/github" + } + } +}