diff --git a/.github/workflows/terraform-release.yaml b/.github/workflows/terraform-release.yaml index b58eb34..319598d 100644 --- a/.github/workflows/terraform-release.yaml +++ b/.github/workflows/terraform-release.yaml @@ -7,7 +7,7 @@ on: - main jobs: terraform-ci-cd: - runs-on: 229685449397 + runs-on: "229685449397" permissions: contents: write diff --git a/README.md b/README.md index 282aa3a..0b51d07 100644 --- a/README.md +++ b/README.md @@ -1,165 +1,144 @@ # terraform-eks-deployment -Terraform module for EKS cluster deployment and configuration +Terraform module for EKS cluster repository bootstrapping and configuration ## Overview -This module creates a new GitHub repository for your EKS cluster based on the template-eks-cluster repository. It sets up all necessary configuration files and triggers automated workflows for cluster deployment. +This module creates and configures a new GitHub repository for your EKS cluster based on the template-eks-cluster repository. It automatically generates all necessary Terragrunt HCL files (`root.hcl`, `account.hcl`, `region.hcl`, etc.) directly from your input variables, eliminating the need for manual configuration or separate Ansible playbooks. + +## Features + +- **Fully Terraform-Native**: No Lambda functions, Ansible playbooks, or manual steps required +- **Complete HCL Generation**: Automatically creates all necessary Terragrunt HCL files +- **Team Management**: Configures repository permissions for your teams +- **Customizable**: Extensive configuration options for cluster, account, and VPC settings ## Prerequisites - GitHub token with repository and workflow permissions -- Python 3.x installed on the machine running Terraform +- Terraform 1.0.0 or newer - Access to GitHub Enterprise (if using enterprise version) ## Usage +### Basic Example + ```hcl module "eks_deployment" { - source = "path/to/terraform-eks-deployment" - - name = "my-eks-cluster" - organization = "my-org" - environment = "production" - region = "us-east-1" + source = "github.com/HappyPathway/terraform-eks-deployment" + + # Repository configuration + repository_name = "eks-prod-cluster" + repository_template_owner = "HappyPathway" + repository_template = "template-eks-cluster" + repository_teams = { + "platform-team" = "admin", + "devops-team" = "maintain", + "developers" = "push" + } - cluster_config = { - cluster_name = "prod-eks-01" - account_name = "prod-account" - aws_account_id = "123456789012" - aws_profile = "prod-profile" + # Basic settings + organization = "my-org" + environment = "production" + region = "us-gov-west-1" + github_server_url = "https://github.e.it.census.gov" # For GitHub Enterprise + + # Account configuration + account_config = { + account_name = "prod-account" + aws_account_id = "123456789012" environment_abbr = "prod" + } + + # VPC configuration + vpc_config = { vpc_name = "prod-vpc" vpc_domain_name = "prod.example.com" } - github_token = "your-github-token" - github_server_url = "https://github.e.it.census.gov" # Optional, for GitHub Enterprise + # Cluster configuration + cluster_config = { + cluster_name = "prod-eks-01" + cluster_mailing_list = "team@example.com" + eks_instance_disk_size = 200 + eks_ng_desired_size = 5 + eks_ng_max_size = 10 + eks_ng_min_size = 3 + organization = "census:ocio:csvd" + finops_project_name = "csvd_platformbaseline" + finops_project_number = "fs0000000078" + finops_project_role = "csvd_platformbaseline_app" + tags = { + Owner = "Platform Team", + Environment = "Production", + CostCenter = "123-456" + } + module_enablement_overrides = { + cert_manager = true, + prometheus = true, + grafana = true, + istio = true + } + } } -``` - -## Workflow Automation - -### Overview - -The module automatically triggers GitHub Actions workflows in your newly created repository to: -1. Install Python requirements -2. Execute Terragrunt operations for cluster management - -### Workflow Sequence - -1. **Repository Creation**: The module creates a new repository from the template-eks-cluster template -2. **Initial Configuration**: Configuration files are generated based on your inputs -3. **Requirements Installation**: A workflow is triggered to install Python dependencies -4. **Cluster Planning**: A terragrunt plan workflow is automatically triggered -### Available Workflows - -Your new repository will have these workflows available: - -1. **Install Requirements** (`install-requirements.yml`) - - Triggered automatically on repository creation - - Installs all Python dependencies from requirements.txt - -2. **Terragrunt Cluster Operations** (`terragrunt-cluster-build.yml`) - - Supports plan, apply, and destroy operations - - Can be triggered manually or via API - - Includes safety checks and approvals - -### Triggering Workflows - -The workflows can be triggered in two ways: - -1. **Automatic Triggering** - - On repository creation, the module automatically triggers: - 1. Requirements installation - 2. Initial cluster plan - -2. **Manual Triggering** - - Via GitHub UI: - 1. Go to Actions tab - 2. Select desired workflow - 3. Click "Run workflow" - 4. Fill in parameters - -3. **API Triggering** - - Use GitHub's API to trigger workflows: - ```bash - curl -X POST \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github.v3+json" \ - "https://api.github.com/repos/OWNER/REPO/dispatches" \ - -d '{ - "event_type": "cluster-plan", - "client_payload": { - "environment": "dev", - "region": "us-east-1", - "cluster_dir": "my-cluster", - "auto_approve": false - } - }' - ``` - -### Supported Events - -The following event types are supported for workflow triggers: +output "repository_url" { + value = module.eks_deployment.repository_url +} +``` -- `install-requirements`: Install Python dependencies -- `cluster-plan`: Preview cluster changes -- `cluster-apply`: Apply cluster changes -- `cluster-destroy`: Destroy cluster +## Generated Files -### Required Secrets +The module automatically generates the following files in your new repository: -The following secrets must be configured in your repository: +- `root.hcl`: Global Terragrunt configuration +- `[environment]/account.hcl`: Account-specific variables +- `[environment]/[region]/region.hcl`: Region-specific variables +- `[environment]/[region]/vpc/vpc.hcl`: VPC-specific variables +- `[environment]/[region]/vpc/[cluster_name]/cluster.hcl`: Cluster-specific variables +- `README.md`: Usage instructions and documentation -- `AWS_ROLE_ARN`: ARN of the AWS role to assume -- `GITHUB_TOKEN`: GitHub token with workflow permissions +These files are committed directly to your new repository and are ready for use with Terragrunt to deploy your EKS cluster. ## Module Configuration ### Required Variables -- `name`: Repository name -- `organization`: GitHub organization name -- `environment`: Deployment environment -- `region`: AWS region -- `cluster_config`: Cluster configuration object -- `github_token`: GitHub token for workflow operations +| Name | Description | +|------|-------------| +| `repository_name` | Name of the GitHub repository to create | +| `organization` | GitHub organization name | +| `environment` | Deployment environment (e.g., production, development) | +| `region` | AWS region for the EKS cluster | +| `account_config` | Map of account configuration values | +| `vpc_config` | Map of VPC configuration values | +| `cluster_config` | Map of cluster configuration values | ### Optional Variables -- `github_server_url`: GitHub Enterprise server URL -- `template_repo_org`: Organization containing the template repository -- `enable_modules`: Map of modules to enable in the cluster +| Name | Description | Default | +|------|-------------|---------| +| `repository_template_owner` | Owner of the template repository | `"HappyPathway"` | +| `repository_template` | Template repository name | `"template-eks-cluster"` | +| `repository_teams` | Map of team names and permission levels | `{}` | +| `github_server_url` | GitHub Enterprise server URL | `"https://api.github.com"` | -For more configuration options, see the variables.tf file. +For complete configuration options, see the variables.tf file. ## Outputs -- `repository_url`: URL of the created repository -- `ssh_clone_url`: SSH clone URL of the repository - -## Security Considerations - -1. **GitHub Token**: Use a token with minimal required permissions -2. **AWS Role**: Use role-based access with least privilege -3. **Auto-approve**: Use with caution in production environments -4. **Environment Protection**: Configure branch protection rules - -## Troubleshooting +| Name | Description | +|------|-------------| +| `repository_url` | URL of the created repository | +| `ssh_clone_url` | SSH clone URL of the repository | -Common issues and solutions: +## How It Works -1. **Workflow Trigger Failures** - - Check GitHub token permissions - - Verify GitHub Enterprise URL (if applicable) - - Check network connectivity +1. The module calls the `terraform-github-repo` module to create a new repository based on your template. +2. It uses Terraform's `templatefile()` function to render Terragrunt HCL files from templates. +3. These rendered files are committed directly to the repository using the `github_repository_file` resource. +4. Team permissions are configured using the `github_team_repository` resource. -2. **Python Requirements** - - Ensure requirements.txt exists in template repository - - Check Python version compatibility +## Migrating from Previous Workflow -3. **AWS Authentication** - - Verify AWS role ARN - - Check AWS credentials configuration +This module replaces the previous Lambda/Ansible-based workflow with a purely Terraform-native approach. If you were previously using the template-automation-lambda to create repositories and then running an Ansible playbook to generate HCL files, you can now accomplish the entire process with just this module. diff --git a/ROADMAP.md b/ROADMAP.md index 12f698f..0667b5a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,62 +1,47 @@ -# EKS Cluster Template Roadmap +# EKS Cluster Deployment 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` +- **Terraform-Native Workflow**: The module provides a fully Terraform-native workflow for bootstrapping a single GitHub repository for an EKS cluster. +- **Declarative Configuration**: It uses a set of input variables (`account_config`, `vpc_config`, `cluster_config`) to define a cluster's configuration. +- **Dynamic HCL Generation**: The module automatically generates all necessary Terragrunt HCL files (`root.hcl`, `account.hcl`, `region.hcl`, etc.) from internal templates. +- **Wrapper Module**: This module acts as a sophisticated wrapper around the `terraform-github-repo` module, orchestrating repository creation, file generation, and team permission management. ## Planned Enhancements -### 1. Automated Cluster Setup (High Priority) -- [x] Add GitHub Actions workflows with workflow_dispatch triggers -- [x] Implement automated terragrunt command execution for cluster building - - [x] Support for plan/apply/destroy commands - - [x] Environment-specific execution - - [x] Automated testing framework -- [ ] 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 +### 1. Version and Configuration Management (High Priority) +- [x] Implement version control strategy for `default-versions.hcl` +- [x] Create system for managing platform release versions +- [x] Set up version override mechanism +- [ ] Add validation for configuration files to fail early on invalid inputs. +- [ ] Integrate a robust versioning strategy for the module itself, using tags. + +### 2. Automated Cluster Deployment (Medium Priority) +- [ ] Create templatized GitHub Actions workflow files that can be injected into the created repository. +- [ ] Configure workflows to run on specific runners for secure credential management. +- [ ] Implement automated `terragrunt plan/apply` execution within the generated workflows. + +### 3. Module and Documentation Refinements (Low Priority) +- [ ] Enhance documentation with more detailed examples, including edge cases. +- [ ] Add contribution guidelines and a developer guide. +- [ ] Refactor and clean up any legacy code or unused variables. + +## Completed Milestones + +- **Terraform-Native Migration**: Successfully replaced the legacy Lambda/Ansible workflow with a unified, Terraform-native solution for repository bootstrapping. +- **File Management System**: Implemented a robust system for crafting and injecting configuration files directly via Terraform, fulfilling the core requirement of the "File Management System" epic. ## 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 +1. **Automation Requirements**: + - GitHub Actions runner configuration for secure AWS authentication. + - Workflow templating to dynamically generate CI/CD pipelines. + - Seamless Terragrunt integration within the automated workflows. + +2. **Version Control Strategy**: + - Centralized management of component versions (EKS, Istio, etc.). + - Clear override mechanisms for environment-specific versioning. ## 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 +- Fully automated repository and cluster configuration process. +- A clear, maintainable, and scalable version management system. +- Secure and automated CI/CD pipelines for deploying EKS clusters. +- Comprehensive documentation that empowers users and contributors. \ No newline at end of file diff --git a/examples/basic/.terraform_commits b/examples/basic/.terraform_commits new file mode 100644 index 0000000..5b4199e --- /dev/null +++ b/examples/basic/.terraform_commits @@ -0,0 +1,62 @@ +[ + { + "commit_hash": "2d1a9976c65f53b370b4a3ff0829394449127d5a", + "commit_message": "Fix formatting of runs-on value in GitHub Actions workflow", + "author": "Your Name", + "timestamp": "2025-09-04T13:49:32.940158" + }, + { + "commit_hash": "2d1a9976c65f53b370b4a3ff0829394449127d5a", + "commit_message": "Fix formatting of runs-on value in GitHub Actions workflow", + "author": "Your Name", + "timestamp": "2025-09-04T13:52:48.384810" + }, + { + "commit_hash": "2d1a9976c65f53b370b4a3ff0829394449127d5a", + "commit_message": "Fix formatting of runs-on value in GitHub Actions workflow", + "author": "Your Name", + "timestamp": "2025-09-04T14:36:08.594715" + }, + { + "commit_hash": "2d1a9976c65f53b370b4a3ff0829394449127d5a", + "commit_message": "Fix formatting of runs-on value in GitHub Actions workflow", + "author": "Your Name", + "timestamp": "2025-09-04T15:59:08.094373" + }, + { + "commit_hash": "94a518393002dd67ec0a178aee46323921889767", + "commit_message": "Refactor README and ROADMAP for clarity; update Terraform configurations and remove deprecated variables", + "author": "Your Name", + "timestamp": "2025-09-05T13:52:50.300053" + }, + { + "commit_hash": "94a518393002dd67ec0a178aee46323921889767", + "commit_message": "Refactor README and ROADMAP for clarity; update Terraform configurations and remove deprecated variables", + "author": "Your Name", + "timestamp": "2025-09-05T13:57:43.873358" + }, + { + "commit_hash": "94a518393002dd67ec0a178aee46323921889767", + "commit_message": "Refactor README and ROADMAP for clarity; update Terraform configurations and remove deprecated variables", + "author": "Your Name", + "timestamp": "2025-09-08T13:08:10.570707" + }, + { + "commit_hash": "94a518393002dd67ec0a178aee46323921889767", + "commit_message": "Refactor README and ROADMAP for clarity; update Terraform configurations and remove deprecated variables", + "author": "Your Name", + "timestamp": "2025-09-10T15:25:49.548237" + }, + { + "commit_hash": "1694ff2abd5271962c65bf1a8798c15cfdcd0af9", + "commit_message": "Update main.tf", + "author": "David John Arnold Jr", + "timestamp": "2025-09-10T17:11:02.705468" + }, + { + "commit_hash": "1694ff2abd5271962c65bf1a8798c15cfdcd0af9", + "commit_message": "Update main.tf", + "author": "David John Arnold Jr", + "timestamp": "2025-09-10T17:17:55.685167" + } +] \ No newline at end of file diff --git a/examples/basic/main.tf b/examples/basic/main.tf index fcc16ea..d84fb0b 100644 --- a/examples/basic/main.tf +++ b/examples/basic/main.tf @@ -1,38 +1,71 @@ +provider "aws" { +} + +data "aws_secretsmanager_secret_version" "github_token" { + secret_id = "/eks-cluster-deployment/github_token" +} + provider "github" { - # Configuration expected from environment variables: - # GITHUB_TOKEN - # GITHUB_OWNER (optional) + token = data.aws_secretsmanager_secret_version.github_token.secret_string } module "eks_deployment" { source = "../../" - name = "eks-test-cluster" - organization = "my-org" - environment = "dev" - region = "us-east-1" + # Repository and cluster configuration - single name for both + name = "eks-test-cluster" + template_repo_org = "SCT-Engineering" + repository_template = "template-eks-cluster" + is_private = false # Set to false to make the repository public + repository_teams = { + "platform-team" = "admin", + "devops-team" = "maintain", + "developers" = "push" + } - template_repo_org = "my-org" + # Basic settings + organization = "SCT-Engineering" + environment = "dev" + region = "us-gov-east-1" github_server_url = "https://github.e.it.census.gov" + # Cluster configuration cluster_config = { - cluster_name = "dev-eks-01" - account_name = "dev-account" - aws_account_id = "123456789012" - aws_profile = "dev-profile" - environment_abbr = "dev" - vpc_name = "dev-vpc" - vpc_domain_name = "dev.example.com" + account_name = "csvd-dev-ew" + aws_account_id = "229685449397" + environment_abbr = "dev" + aws_profile = "default" + vpc_name = "vpc3-csvd-dev" + vpc_domain_name = "dev.inf.csp1.census.gov" + cluster_mailing_list = "david.j.arnold.jr@census.gov" + eks_instance_disk_size = 100 + eks_ng_desired_size = 3 + eks_ng_max_size = 6 + eks_ng_min_size = 2 + organization = "census:ocio:csvd" + finops_project_name = "csvd_platformbaseline" + finops_project_number = "fs0000000078" + finops_project_role = "csvd_platformbaseline_app" + tags = { + Owner = "Platform Team", + Environment = "Development", + CostCenter = "123-456" + } + module_enablement_overrides = { + cert_manager = true, + prometheus = true, + grafana = true, + istio = false + } } +} - enable_modules = { - cert_manager = true - prometheus = true - grafana = true - } +output "repository_url" { + description = "URL of the created GitHub repository" + value = module.eks_deployment.repository_url +} - versions = { - cluster_version = "1.27" - eks_module_version = "20.33.1" - } -} \ No newline at end of file +output "ssh_clone_url" { + description = "SSH clone URL of the repository" + value = module.eks_deployment.ssh_clone_url +} diff --git a/examples/basic/varfiles/default.json b/examples/basic/varfiles/default.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/examples/basic/varfiles/default.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/examples/basic/variables.tf b/examples/basic/variables.tf deleted file mode 100644 index 73092ff..0000000 --- a/examples/basic/variables.tf +++ /dev/null @@ -1,5 +0,0 @@ -variable "github_token" { - description = "GitHub token for API operations" - type = string - sensitive = true -} \ No newline at end of file diff --git a/examples/centralized-management/main.tf b/examples/centralized-management/main.tf new file mode 100644 index 0000000..5e09a13 --- /dev/null +++ b/examples/centralized-management/main.tf @@ -0,0 +1,126 @@ +# Example: Centralized EKS Repository Management +# +# This example demonstrates how to use the terraform-eks-deployment module +# to manage multiple EKS cluster repositories from a central location. + +provider "github" { + # Configuration expected from environment variables: + # GITHUB_TOKEN + # GITHUB_OWNER (optional) + + # For GitHub Enterprise Server + base_url = var.github_server_url +} + +# Production EKS Cluster Repository +module "prod_eks_cluster" { + source = "../../" + + # Repository and cluster configuration - single name for both + name = "eks-prod-cluster" # This name is used for both the repository and cluster + template_repo_org = "HappyPathway" + repository_template = "template-eks-cluster" + repository_teams = { + "platform-team" = "admin", + "prod-sre-team" = "maintain", + "developers" = "triage" + } + + # Basic settings + organization = var.github_organization + environment = "production" + region = "us-gov-west-1" + github_server_url = var.github_server_url + + # Cluster configuration + cluster_config = { + account_name = "prod-account" + aws_account_id = var.prod_account_id + environment_abbr = "prod" + aws_profile = "default" + vpc_name = "prod-vpc" + vpc_domain_name = "prod.example.com" + cluster_mailing_list = "prod-alerts@example.com" + eks_instance_disk_size = 200 + eks_ng_desired_size = 5 + eks_ng_max_size = 10 + eks_ng_min_size = 3 + organization = "census:ocio:csvd" + finops_project_name = "csvd_platformbaseline" + finops_project_number = "fs0000000078" + finops_project_role = "csvd_platformbaseline_app" + tags = { + Owner = "Platform Team", + Environment = "Production", + CostCenter = "123-456" + } + module_enablement_overrides = { + cert_manager = true, + prometheus = true, + grafana = true, + istio = true + } + } +} + +# Development EKS Cluster Repository +module "dev_eks_cluster" { + source = "../../" + + # Repository and cluster configuration - single name for both + name = "eks-dev-cluster" # This name is used for both the repository and cluster + template_repo_org = "HappyPathway" + repository_template = "template-eks-cluster" + repository_teams = { + "platform-team" = "admin", + "dev-team" = "maintain", + "developers" = "push" + } + + # Basic settings + organization = var.github_organization + environment = "development" + region = "us-gov-west-1" + github_server_url = var.github_server_url + + # Cluster configuration + cluster_config = { + account_name = "dev-account" + aws_account_id = var.dev_account_id + environment_abbr = "dev" + aws_profile = "default" + vpc_name = "dev-vpc" + vpc_domain_name = "dev.example.com" + cluster_mailing_list = "dev-alerts@example.com" + eks_instance_disk_size = 100 + eks_ng_desired_size = 2 + eks_ng_max_size = 5 + eks_ng_min_size = 1 + organization = "census:ocio:csvd" + finops_project_name = "csvd_platformbaseline" + finops_project_number = "fs0000000078" + finops_project_role = "csvd_platformbaseline_app" + tags = { + Owner = "Platform Team", + Environment = "Development", + CostCenter = "123-456" + } + module_enablement_overrides = { + cert_manager = true, + prometheus = true, + grafana = false, + istio = false + } + } +} + +# Output repository URLs +output "prod_repository_url" { + description = "URL of the production EKS cluster repository" + value = module.prod_eks_cluster.repository_url +} + +output "dev_repository_url" { + description = "URL of the development EKS cluster repository" + value = module.dev_eks_cluster.repository_url +} \ No newline at end of file diff --git a/examples/centralized-management/variables.tf b/examples/centralized-management/variables.tf new file mode 100644 index 0000000..9522f71 --- /dev/null +++ b/examples/centralized-management/variables.tf @@ -0,0 +1,23 @@ +variable "github_organization" { + description = "GitHub organization name" + type = string + default = "HappyPathway" +} + +variable "github_server_url" { + description = "GitHub Enterprise server URL (e.g., https://github.e.it.census.gov)" + type = string + default = "https://api.github.com" +} + +variable "prod_account_id" { + description = "AWS account ID for production" + type = string + default = "123456789012" +} + +variable "dev_account_id" { + description = "AWS account ID for development" + type = string + default = "210987654321" +} \ No newline at end of file diff --git a/locals.tf b/locals.tf index bc33459..3748484 100644 --- a/locals.tf +++ b/locals.tf @@ -1,166 +1,166 @@ locals { common_vars = merge({ - organization = "census:ocio:csvd" - project_name = "csvd_platformbaseline" - project_number = "fs0000000078" - project_role = "csvd_platformbaseline_app" + 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 = {} + state_table_name = "tf_remote_state" + route53_endpoints = {} }, var.common_variables) # First define base namespaces without dependencies base_namespaces = { - cert-manager = "kube-system" - karpenter = "karpenter" + cert-manager = "kube-system" + karpenter = "karpenter" metrics-server = "kube-system" - postgresql = "kube-system" - keycloak = "keycloak" - gogatekeeper = "kube-system" - istio = "istio-system" - kiali = "istio-system" + postgresql = "kube-system" + keycloak = "keycloak" + gogatekeeper = "kube-system" + istio = "istio-system" + kiali = "istio-system" } # Then merge with telemetry namespaces all_namespaces = merge( local.base_namespaces, { - grafana = var.namespaces.telemetry_namespace + grafana = var.namespaces.telemetry_namespace k8s-dashboard = var.namespaces.telemetry_namespace - loki = var.namespaces.telemetry_namespace - otel = var.namespaces.telemetry_namespace - prometheus = var.namespaces.telemetry_namespace - tempo = var.namespaces.telemetry_namespace + loki = var.namespaces.telemetry_namespace + otel = var.namespaces.telemetry_namespace + prometheus = var.namespaces.telemetry_namespace + tempo = var.namespaces.telemetry_namespace }, var.namespaces.custom_namespaces ) namespaces = { - operator_namespace = var.namespaces.operator_namespace + operator_namespace = var.namespaces.operator_namespace telemetry_namespace = var.namespaces.telemetry_namespace - namespaces = local.all_namespaces + namespaces = local.all_namespaces } default_versions = { - cluster_version = var.versions.cluster_version + 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 + 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 + 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 + 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_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 + cluster_issuer_name = var.versions.cert_manager.cluster_issuer_name - gogatekeeper_tag = var.versions.gogatekeeper.tag + gogatekeeper_tag = var.versions.gogatekeeper.tag gogatekeeper_chart_version = var.versions.gogatekeeper.chart_version - grafana_hostname = var.versions.grafana.hostname + 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 + 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_version = var.versions.istio.version istio_namespace = var.versions.istio.namespace - dashboard_hostname = var.versions.k8s_dashboard.hostname + 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 + k8s_dashboard_version = var.versions.k8s_dashboard.version karpenter_helm_chart = var.versions.karpenter.helm_chart - karpenter_tag = var.versions.karpenter.tag + 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 + 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 + 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 + 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 + 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_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 + 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 + tempo_tag = var.versions.tempo.tag # Add namespace configurations - operator_namespace = var.namespaces.operator_namespace + operator_namespace = var.namespaces.operator_namespace telemetry_namespace = var.namespaces.telemetry_namespace - namespaces = local.all_namespaces + namespaces = local.all_namespaces } config_json = jsonencode({ - environment = var.environment - region = var.region - cluster_dir = "platform-cluster" + environment = var.environment + region = var.region + cluster_dir = "platform-cluster" enable_all_modules = var.enable_all_modules account = { - account_name = var.cluster_config.account_name - aws_account_id = var.cluster_config.aws_account_id - aws_profile = var.cluster_config.aws_profile + 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_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 + cluster_name = var.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 + tags = var.cluster_config.tags } modules = var.enable_modules }) managed_extra_files = concat([ { - path = "config.json" + path = "config.json" content = local.config_json }, { - path = "_envcommon/default-versions.hcl" + path = "_envcommon/default-versions.hcl" content = templatefile("${path.module}/templates/default-versions.hcl", local.default_versions) }, { - path = "_envcommon/common-variables.hcl" + 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 index a3f9395..af88a2b 100644 --- a/main.tf +++ b/main.tf @@ -1,44 +1,89 @@ +locals { + rendered_files = { + "root.hcl" : templatefile("${path.module}/templates/root.hcl.tf.tpl", { + environment = var.environment + }), + "environment/account.hcl" : templatefile("${path.module}/templates/account.hcl.tf.tpl", { + account_name = var.cluster_config.account_name, + aws_account_id = var.cluster_config.aws_account_id, + environment = var.environment, + environment_abbr = var.cluster_config.environment_abbr + }), + "environment/region/region.hcl" : templatefile("${path.module}/templates/region.hcl.tf.tpl", { + aws_region = var.region, + environment = var.environment + }), + "environment/region/vpc/vpc.hcl" : templatefile("${path.module}/templates/vpc.hcl.tf.tpl", { + vpc_name = var.cluster_config.vpc_name, + vpc_domain_name = var.cluster_config.vpc_domain_name, + environment = var.environment, + aws_region = var.region + }), + "environment/region/vpc/cluster/cluster.hcl" : templatefile("${path.module}/templates/cluster.hcl.tf.tpl", { + cluster_name = var.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, + organization = var.cluster_config.organization, + finops_project_name = var.cluster_config.finops_project_name, + finops_project_number = var.cluster_config.finops_project_number, + finops_project_role = var.cluster_config.finops_project_role, + tags = var.cluster_config.tags, + module_enablement_overrides = var.cluster_config.module_enablement_overrides + }), + "README.md" : templatefile("${path.module}/templates/README.md.tf.tpl", { + environment = var.environment, + cluster_name = var.name, + aws_region = var.region + }) + } +} + 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 + source = "github.com/HappyPathway/terraform-github-repo" - managed_extra_files = concat( - local.managed_extra_files, - var.managed_extra_files - ) - extra_files = var.extra_files -} + name = var.name + repo_org = var.organization + github_repo_description = "EKS Cluster Configuration for ${var.name}" + github_repo_topics = ["eks", "kubernetes", "terraform", "infrastructure"] + force_name = var.force_name -resource "null_resource" "trigger_workflow" { - triggers = { - github_repo_name = module.github_repo.full_name - } + template_repo_org = var.repository_template_owner + template_repo = var.repository_template - provisioner "local-exec" { - command = "python3 scripts/trigger_workflow.py ${module.github_repo.full_name} cluster-plan '{\"environment\":\"${var.environment}\",\"region\":\"${var.region}\",\"cluster_dir\":\"${var.cluster_config.cluster_name}\",\"auto_approve\":true}'" - } + github_is_private = var.is_private + github_has_issues = true + github_has_wiki = true + github_has_projects = true - depends_on = [module.github_repo] + managed_extra_files = [ + for path, content in local.rendered_files : { + path = path + content = content + } + ] + archive_on_destroy = false + github_org_teams = [ + for team, permission in var.repository_teams : { + team_name = team + permission = permission + slug = lower(replace(team, " ", "-")) + id = null # Changed from team_id to id as expected by the module + bypass_rules = false + } + ] } +# The EKS deployment logic will go here, and will be skipped if create_repository is true. + output "repository_url" { description = "URL of the created repository" - value = module.github_repo.html_url + value = module.github_repo.html_url } output "ssh_clone_url" { description = "SSH clone URL of the repository" - value = module.github_repo.ssh_clone_url + value = module.github_repo.ssh_clone_url } \ No newline at end of file diff --git a/providers.tf b/providers.tf index e01c942..c5ea7b3 100644 --- a/providers.tf +++ b/providers.tf @@ -4,11 +4,9 @@ terraform { source = "integrations/github" version = ">= 5.0" } + aws = { + source = "hashicorp/aws" + version = ">= 5.0" + } } -} - -provider "github" { - # Configuration is expected from environment variables: - # GITHUB_TOKEN - # GITHUB_OWNER (optional) } \ No newline at end of file diff --git a/templates/README.md.tf.tpl b/templates/README.md.tf.tpl new file mode 100644 index 0000000..75175a8 --- /dev/null +++ b/templates/README.md.tf.tpl @@ -0,0 +1,39 @@ +# EKS Cluster Configuration - ${upper(environment)} + +This EKS cluster configuration was generated using Terraform and the terraform-eks-deployment module. + +## Environment Details + +- **Environment**: ${environment} +- **Region**: ${aws_region} +- **Cluster Name**: ${cluster_name} + +## Directory Structure + +## Getting Started + +To apply this configuration: + +1. Change to the directory of the module you want to deploy: + ``` + cd environment/region/vpc/cluster/eks + ``` + +2. Initialize and apply the Terragrunt configuration: + ``` + terragrunt init + terragrunt plan + terragrunt apply + ``` + +3. Deploy additional modules as needed: + ``` + cd ../eks-cert-manager + terragrunt init + terragrunt plan + terragrunt apply + ``` + +## Customization + +Each module can be deployed independently using Terragrunt. \ No newline at end of file diff --git a/templates/account.hcl.tf.tpl b/templates/account.hcl.tf.tpl new file mode 100644 index 0000000..83d3336 --- /dev/null +++ b/templates/account.hcl.tf.tpl @@ -0,0 +1,11 @@ +# ${environment}/environment.hcl + +# Set account-wide variables. These are automatically pulled in to configure the remote state bucket in the root +# terragrunt.hcl configuration. +locals { + account_name = "${account_name}" + aws_account_id = "${aws_account_id}" + aws_profile = format("%v-%v", local.aws_account_id, replace(local.account_name, "-ew", "-gov")) + environment = "${environment}" + environment_abbr = "${environment_abbr}" +} diff --git a/templates/cluster.hcl.tf.tpl b/templates/cluster.hcl.tf.tpl new file mode 100644 index 0000000..0a30d6c --- /dev/null +++ b/templates/cluster.hcl.tf.tpl @@ -0,0 +1,15 @@ +locals { + # Cluster specific configuration + cluster_name = "${cluster_name}" + cluster_mailing_list = "${cluster_mailing_list}" + eks_instance_disk_size = ${eks_instance_disk_size} + eks_ng_desired_size = ${eks_ng_desired_size} + eks_ng_max_size = ${eks_ng_max_size} + eks_ng_min_size = ${eks_ng_min_size} + organization = "${organization}" + finops_project_name = "${finops_project_name}" + finops_project_number = "${finops_project_number}" + finops_project_role = "${finops_project_role}" + tags = ${jsonencode(tags)} + module_enablement_overrides = ${jsonencode(module_enablement_overrides)} +} diff --git a/templates/region.hcl.tf.tpl b/templates/region.hcl.tf.tpl new file mode 100644 index 0000000..dc6c306 --- /dev/null +++ b/templates/region.hcl.tf.tpl @@ -0,0 +1,7 @@ +# ${environment}/${aws_region}/region.hcl + +# Set common variables for the region. This is automatically pulled in in the root terragrunt.hcl configuration to +# configure the remote state bucket and pass forward to the child modules as inputs. +locals { + aws_region = "${aws_region}" +} diff --git a/templates/root.hcl.tf.tpl b/templates/root.hcl.tf.tpl new file mode 100644 index 0000000..2946d47 --- /dev/null +++ b/templates/root.hcl.tf.tpl @@ -0,0 +1,171 @@ +# $${environment}/root.hcl +# --------------------------------------------------------------------------------------------------------------------- +# TERRAGRUNT CONFIGURATION +# Terragrunt is a thin wrapper for Terraform that provides extra tools for working with multiple Terraform modules, +# remote state, and locking: https://github.com/gruntwork-io/terragrunt +# --------------------------------------------------------------------------------------------------------------------- +locals { + # Automatically load account-level variables (NOTE: In our environment account = environment so there is not separate environment layer) + account_vars = read_terragrunt_config(find_in_parent_folders("account.hcl")) + + # Automatically load cluster-level variables + cluster_vars = read_terragrunt_config(find_in_parent_folders("cluster.hcl")) + + # Automatically load _envcommon, cross account and environment common variables + common_vars = read_terragrunt_config(find_in_parent_folders("./_envcommon/common-variables.hcl")) + + # Automatically load naming prefixes + prefix_vars = read_terragrunt_config(find_in_parent_folders("./_envcommon/prefixes.hcl")) + + # Automatically load region-level variables + region_vars = read_terragrunt_config(find_in_parent_folders("region.hcl")) + + # Automatically load versions + versions = read_terragrunt_config(find_in_parent_folders("./_envcommon/default-versions.hcl")) + + # Automatically load vpc-level variables + vpc_vars = read_terragrunt_config(find_in_parent_folders("vpc.hcl")) + + # Add any other locals you want to expose + # only expose things not already included via local.xxx_vars.locals.* + root_locals_for_inputs = { + is_module_enabled = local.is_module_enabled + module_name = local.module_name + } + + # Extract the variables we need for easy access + account_id = local.account_vars.locals.aws_account_id + account_name = local.account_vars.locals.account_name + aws_profile = local.account_vars.locals.aws_profile + aws_region = local.region_vars.locals.aws_region + cluster_name = local.cluster_vars.locals.cluster_name + eecr_info = local.common_vars.locals.eecr_info + environment_abbr = local.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 +} + +# Only generate providers for non-EKS modules +generate "cluster_data" { + path = "cluster-data.tf" + if_exists = "overwrite_terragrunt" + contents = local.is_eks_module ? "" : <<-EOF + data "aws_eks_clusters" "available" {} + + locals { + cluster_exists = contains(data.aws_eks_clusters.available.names, "$${local.cluster_name}") + } + + data "aws_eks_cluster" "this" { + count = local.cluster_exists ? 1 : 0 + name = "$${local.cluster_name}" + } + + data "aws_eks_cluster_auth" "this" { + count = local.cluster_exists ? 1 : 0 + name = "$${local.cluster_name}" + } + EOF +} + +# Generate provider blocks only for non-EKS modules +generate "kube_provider" { + path = "kube-provider.tf" + if_exists = "overwrite_terragrunt" + contents = local.is_eks_module ? "" : <<-EOF + provider "kubernetes" { + host = local.cluster_exists ? data.aws_eks_cluster.this[0].endpoint : "https://dummy" + cluster_ca_certificate = local.cluster_exists ? base64decode(data.aws_eks_cluster.this[0].certificate_authority[0].data) : null + token = local.cluster_exists ? data.aws_eks_cluster_auth.this[0].token : "dummy" + } + EOF +} + +generate "helm_provider" { + path = "helm-provider.tf" + if_exists = "overwrite_terragrunt" + contents = local.is_eks_module ? "" : <<-EOF + provider "helm" { + kubernetes = { + host = local.cluster_exists ? data.aws_eks_cluster.this[0].endpoint : "https://dummy" + cluster_ca_certificate = local.cluster_exists ? base64decode(data.aws_eks_cluster.this[0].certificate_authority[0].data) : null + token = local.cluster_exists ? data.aws_eks_cluster_auth.this[0].token : "dummy" + } + } + EOF +} + +# Configure Terragrunt to automatically store tfstate files in an S3 bucket +remote_state { + disable_init = tobool(get_env("TG_DISABLE_INIT", "false")) + backend = "s3" + generate = { + path = "remote_state.backend.tf" + if_exists = "overwrite_terragrunt" + } + config = { + bucket = "$${local.state_bucket_prefix}-$${local.account_id}" + use_lockfile = true + key = "$${trimprefix(replace(run_cmd("realpath", get_original_terragrunt_dir()), dirname(get_repo_root()), ""), "/")}/terraform.tfstate" + profile = "$${local.aws_profile}" + region = "$${local.aws_region}" + disable_bucket_update = true + } +} + +# Generate an AWS provider block +generate "aws-provider" { + path = "aws-provider.tf" + if_exists = "overwrite" + contents = <<-EOF + provider "aws" { + region = "$${local.aws_region}" + profile = "$${local.aws_profile}" + default_tags { + tags = { + cluster_name = "$${local.cluster_name}" + "boc:module_name" = "$${local.module_name}" + environment = "$${local.environment_abbr}" + finops_project_name = "$${local.finops_project_name}" + finops_project_number = "$${local.finops_project_number}" + finops_project_role = "$${local.finops_project_role}" + organization = "$${local.organization}" + } + } + # Only these AWS Account IDs may be operated on by this template + allowed_account_ids = ["$${local.account_id}"] + } +EOF +} + +# --------------------------------------------------------------------------------------------------------------------- +# GLOBAL PARAMETERS +# These variables apply to all configurations in this subfolder. These are automatically merged into the child +# `terragrunt.hcl` config via the include block. +# --------------------------------------------------------------------------------------------------------------------- + +# Configure root level variables that all resources can inherit. This is especially helpful with multi-account configs +# where terraform_remote_state data sources are placed directly into the modules. +inputs = merge( + local.account_vars.locals, + local.cluster_vars.locals, + local.common_vars.locals, + local.prefix_vars.locals, + local.region_vars.locals, + local.versions.locals, + local.vpc_vars.locals, + local.root_locals_for_inputs +) diff --git a/templates/vpc.hcl.tf.tpl b/templates/vpc.hcl.tf.tpl new file mode 100644 index 0000000..9e95ad9 --- /dev/null +++ b/templates/vpc.hcl.tf.tpl @@ -0,0 +1,8 @@ +# ${environment}/${aws_region}/vpc/vpc.hcl + +# Set VPC specific variables. These are automatically pulled in to configure the remote state bucket in the root +# terragrunt.hcl configuration. +locals { + vpc_name = "${vpc_name}" + vpc_domain_name = "${vpc_domain_name}" +} diff --git a/varfiles/default.json b/varfiles/default.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/varfiles/default.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/variables.tf b/variables.tf index 23992cc..bbe40c8 100644 --- a/variables.tf +++ b/variables.tf @@ -1,11 +1,12 @@ variable "name" { - description = "Name of the repository" + description = "The name of the repository and EKS cluster. This name will be used for both the GitHub repository and the EKS cluster." type = string } variable "organization" { - description = "GitHub organization name" + description = "The organization to create the repository in." type = string + default = "HappyPathway" } variable "template_repo_org" { @@ -26,15 +27,15 @@ variable "region" { 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") + 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") + state_table_name = optional(string, "tf_remote_state") route53_endpoints = optional(map(object({ - account_id = string - alias = string + account_id = string + alias = string us-gov-east-1 = string us-gov-west-1 = string })), {}) @@ -46,62 +47,62 @@ variable "versions" { description = "Version configurations for various components" type = object({ # Module Versions - cluster_version = optional(string, "1.31") + cluster_version = optional(string, "1.31") eks_module_version = optional(string, "20.33.1") - release_version = optional(string, "main") + release_version = optional(string, "main") # TF Providers - aws_version = optional(string, "5.84.0") - helm_version = optional(string, "2.11.0") + 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") + 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") + 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") + tag = optional(string, "3.2.1") chart_version = optional(string, "0.1.53") }), {}) grafana = optional(object({ - hostname = optional(string, "grafana") + 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") + 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") + version = optional(string, "1.25.0") namespace = optional(string, "istio-system") }), {}) k8s_dashboard = optional(object({ - hostname = optional(string, "dashboard") + hostname = optional(string, "dashboard") metrics_scraper = optional(string, "1.0.8") - version = optional(string, "6.0.6") + version = optional(string, "6.0.6") }), {}) karpenter = optional(object({ helm_chart = optional(string, "1.3.1") - tag = 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") + 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") }), {}) @@ -110,33 +111,33 @@ variable "versions" { }), {}) loki = optional(object({ - chart_version = optional(string, "6.27.0") - tag = optional(string, "3.4.2") + 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") + 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") + 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") + 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") + 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") + tag = optional(string, "2.7.1") }), {}) }) default = {} @@ -145,17 +146,17 @@ variable "versions" { variable "namespaces" { description = "Namespace configurations" type = object({ - operator_namespace = optional(string, "aoperator") + operator_namespace = optional(string, "aoperator") telemetry_namespace = optional(string, "atelemetry") custom_namespaces = optional(map(string), { - cert-manager = "kube-system" - karpenter = "karpenter" + cert-manager = "kube-system" + karpenter = "karpenter" metrics-server = "kube-system" - postgresql = "kube-system" - keycloak = "keycloak" - gogatekeeper = "kube-system" - istio = "istio-system" - kiali = "istio-system" + postgresql = "kube-system" + keycloak = "keycloak" + gogatekeeper = "kube-system" + istio = "istio-system" + kiali = "istio-system" }) }) default = {} @@ -164,20 +165,24 @@ variable "namespaces" { 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) + 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), {}) + tags = optional(map(string), {}) + module_enablement_overrides = optional(map(bool), {}) + finops_project_name = optional(string) + finops_project_number = optional(string) + finops_project_role = optional(string) + organization = optional(string) }) } @@ -186,9 +191,9 @@ variable "enable_modules" { type = object({ gogatekeeper = optional(bool, false) cert_manager = optional(bool, false) - prometheus = optional(bool, false) - grafana = optional(bool, false) - istio = optional(bool, false) + prometheus = optional(bool, false) + grafana = optional(bool, false) + istio = optional(bool, false) }) default = {} } @@ -196,7 +201,7 @@ variable "enable_modules" { variable "github_actions_workflows" { description = "List of GitHub Actions workflow files to add to the repository" type = list(object({ - path = string + path = string content = string })) default = [] @@ -230,4 +235,46 @@ variable "extra_files" { content = string })) default = [] +} + +variable "tags" { + description = "A map of tags to add to all resources." + type = map(string) + default = {} +} + +variable "create_repository" { + description = "If true, a GitHub repository will be created and configured." + type = bool + default = false +} + +variable "repository_teams" { + description = "A map of teams and their permissions to grant on the repository." + type = map(string) + default = {} +} + +variable "repository_template" { + description = "The template repository to use when creating the new repository." + type = string + default = "template-eks-cluster" +} + +variable "repository_template_owner" { + description = "The owner of the template repository." + type = string + default = "SCT-Engineering" +} + +variable "is_private" { + description = "Whether the repository should be private." + type = bool + default = true +} + +variable "force_name" { + description = "Keep exact repository name (no date suffix)" + type = bool + default = true } \ No newline at end of file