From a6d35ede7c7fef7fee4a6e7b6dec4850c596516d Mon Sep 17 00:00:00 2001 From: juandiegocv27 Date: Mon, 1 Dec 2025 20:12:41 -0600 Subject: [PATCH 1/2] chore: finalize infra v1 with VPC module docs and pre-commit --- .gitignore | 7 +++++++ core/vpc/README.md | 5 +++++ envs/dev/!! | 9 --------- envs/dev/1! | 18 ------------------ vpc/README.md | 24 ++++++++++++++---------- vpc/main.tf | 3 +++ vpc/outputs.tf | 10 +++++++--- vpc/variables.tf | 21 ++++++++++++++------- 8 files changed, 50 insertions(+), 47 deletions(-) delete mode 100644 envs/dev/!! delete mode 100644 envs/dev/1! diff --git a/.gitignore b/.gitignore index e5b359b..ea1a7b4 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,10 @@ talos_backup_*/ *.backup *.tfstate *.tfstate.* + +# Terraform local state (bootstrap) +backend/ +*.tfstate +*.tfstate.backup +.terraform/ +.terraform.lock.hcl diff --git a/core/vpc/README.md b/core/vpc/README.md index 748ef41..9d4ea3b 100644 --- a/core/vpc/README.md +++ b/core/vpc/README.md @@ -1,3 +1,8 @@ +> [!NOTE] +> Experimental VPC module. +> Not used by any environment in infra v1. +> Reserved for future refactors (infra v2). + # vpc diff --git a/envs/dev/!! b/envs/dev/!! deleted file mode 100644 index 1bb6a6e..0000000 --- a/envs/dev/!! +++ /dev/null @@ -1,9 +0,0 @@ -terraform { - backend "s3" { - bucket = "shopstack-dev-tfstate" - key = "envs/dev/terraform.tfstate" - region = "us-east-1" - encrypt = true - dynamodb_table = "shopstack-dev-locks" - } -} diff --git a/envs/dev/1! b/envs/dev/1! deleted file mode 100644 index 82d2a40..0000000 --- a/envs/dev/1! +++ /dev/null @@ -1,18 +0,0 @@ -locals { - project = "shopstack" - env = "dev" -} - -module "network" { - source = "../../vpc" - - project = local.project - env = local.env - region = "us-east-1" - vpc_cidr = "10.0.0.0/16" - azs = ["us-east-1a", "us-east-1b"] - public_subnet_cidrs = ["10.0.0.0/24", "10.0.1.0/24"] - private_subnet_cidrs = ["10.0.10.0/24", "10.0.11.0/24"] -} - - diff --git a/vpc/README.md b/vpc/README.md index cdc9a8f..d1af2a6 100644 --- a/vpc/README.md +++ b/vpc/README.md @@ -1,3 +1,7 @@ +> [!NOTE] +> Active VPC module for ShopStack infra v1. +> Used by `envs/dev/main.tf` via `source = "../../vpc"`. + # vpc @@ -26,19 +30,19 @@ No resources. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [azs](#input\_azs) | n/a | `list(string)` | n/a | yes | -| [env](#input\_env) | n/a | `string` | n/a | yes | -| [private\_subnet\_cidrs](#input\_private\_subnet\_cidrs) | n/a | `list(string)` | n/a | yes | -| [project](#input\_project) | n/a | `string` | n/a | yes | -| [public\_subnet\_cidrs](#input\_public\_subnet\_cidrs) | n/a | `list(string)` | n/a | yes | -| [region](#input\_region) | n/a | `string` | n/a | yes | -| [vpc\_cidr](#input\_vpc\_cidr) | n/a | `string` | n/a | yes | +| [azs](#input\_azs) | List of Availability Zones where subnets will be created. | `list(string)` | n/a | yes | +| [env](#input\_env) | Deployment environment (e.g., dev, prod). | `string` | n/a | yes | +| [private\_subnet\_cidrs](#input\_private\_subnet\_cidrs) | List of CIDR blocks for the private subnets. | `list(string)` | n/a | yes | +| [project](#input\_project) | Project name used for resource naming and tagging. | `string` | n/a | yes | +| [public\_subnet\_cidrs](#input\_public\_subnet\_cidrs) | List of CIDR blocks for the public subnets. | `list(string)` | n/a | yes | +| [region](#input\_region) | AWS region where the VPC resources are created. | `string` | n/a | yes | +| [vpc\_cidr](#input\_vpc\_cidr) | Primary CIDR block for the VPC. | `string` | n/a | yes | ## Outputs | Name | Description | |------|-------------| -| [private\_subnets](#output\_private\_subnets) | n/a | -| [public\_subnets](#output\_public\_subnets) | n/a | -| [vpc\_id](#output\_vpc\_id) | n/a | +| [private\_subnets](#output\_private\_subnets) | List of private subnet IDs created in the VPC. | +| [public\_subnets](#output\_public\_subnets) | List of public subnet IDs created in the VPC. | +| [vpc\_id](#output\_vpc\_id) | ID of the VPC created by this module. | diff --git a/vpc/main.tf b/vpc/main.tf index e187591..a7b0e11 100644 --- a/vpc/main.tf +++ b/vpc/main.tf @@ -2,6 +2,9 @@ provider "aws" { region = var.region } + +# Base VPC module for the ShopStack environment. +# Uses terraform-aws-modules/vpc. NAT Gateway is disabled to reduce cost. module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "5.8.1" diff --git a/vpc/outputs.tf b/vpc/outputs.tf index fdb0c6f..039783f 100644 --- a/vpc/outputs.tf +++ b/vpc/outputs.tf @@ -1,11 +1,15 @@ output "vpc_id" { - value = module.vpc.vpc_id + description = "ID of the VPC created by this module." + value = module.vpc.vpc_id } output "public_subnets" { - value = module.vpc.public_subnets + description = "List of public subnet IDs created in the VPC." + value = module.vpc.public_subnets } output "private_subnets" { - value = module.vpc.private_subnets + description = "List of private subnet IDs created in the VPC." + value = module.vpc.private_subnets } + diff --git a/vpc/variables.tf b/vpc/variables.tf index 9d47905..d355e13 100644 --- a/vpc/variables.tf +++ b/vpc/variables.tf @@ -1,27 +1,34 @@ variable "project" { - type = string + type = string + description = "Project name used for resource naming and tagging." } variable "env" { - type = string + type = string + description = "Deployment environment (e.g., dev, prod)." } variable "region" { - type = string + type = string + description = "AWS region where the VPC resources are created." } variable "vpc_cidr" { - type = string + type = string + description = "Primary CIDR block for the VPC." } variable "azs" { - type = list(string) + type = list(string) + description = "List of Availability Zones where subnets will be created." } variable "public_subnet_cidrs" { - type = list(string) + type = list(string) + description = "List of CIDR blocks for the public subnets." } variable "private_subnet_cidrs" { - type = list(string) + type = list(string) + description = "List of CIDR blocks for the private subnets." } From d7b224d3b8d755544f2677a31d787bd62dea86bd Mon Sep 17 00:00:00 2001 From: juandiegocv27 Date: Mon, 1 Dec 2025 20:47:15 -0600 Subject: [PATCH 2/2] docs: define AWS integration scope for infra v1 --- docs/ARCHITECTURE.md | 78 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 15 deletions(-) diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 2abe19a..c067c5c 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -7,10 +7,48 @@ A complete overview of the **ShopStack** project architecture and repository rel ## 📦 **Repositories Overview** | Repository | Purpose | Main Technologies | -|-------------|----------|-------------------| -| **infra-terraform** | Defines and provisions the foundational infrastructure (S3 backend, DynamoDB for locks, Terraform remote state). | Terraform, AWS | -| **cluster-gitops** | Manages cluster provisioning, configuration, and repeatability testing using Kind and GitOps workflows. | Kind, Kubectl, Makefile | -| **apps-sre** | Hosts applications and observability stacks that run inside the Kubernetes cluster. | Docker, Helm, ArgoCD *(future)* | +|-----------|---------|-------------------| +| **infra-terraform** | Defines and provisions the foundational AWS infrastructure (Terraform remote state backend, IAM/OIDC integration, ECR, Secrets Manager, and build hooks). | Terraform, AWS (S3, DynamoDB, IAM, ECR, Secrets Manager) | +| **cluster-gitops** | Manages cluster provisioning, configuration, and repeatability testing using Kind and GitOps workflows. | Kind, kubectl, Makefile | +| **apps-sre** | Hosts applications and observability stacks that run inside the Kubernetes cluster. | Docker, Helm, Argo CD *(future)* | + +--- + +## ☁️ **AWS Integration Scope (infra v1)** + +This section defines the AWS integration scope for **infra v1** of ShopStack. + +- **Terraform remote state backend** + - `core/backend` module creates: + - An S3 bucket to store Terraform remote state. + - A DynamoDB table to provide state locking. + - Used by `envs/dev` to safely manage infrastructure changes. + +- **Secrets Manager** + - AWS Secrets Manager will store runtime secrets for ShopStack (API keys, database credentials, etc.). + - `core/secrets` module (infra-terraform) manages the secret metadata and naming convention (e.g. `shopstack/dev/app-config`). + - Secret values can be injected later into workloads (Kubernetes manifests or app configs) in future sprints. + +- **ECR (Elastic Container Registry)** + - `core/ecr` module provisions an ECR repository per environment (e.g. `shopstack-dev`). + - Used to store container images built for ShopStack applications. + - Images are pushed from CI (GitHub Actions / CodeBuild) and later pulled by the runtime environment (Kind/Talos/EKS). + +- **CodeBuild (build integration)** + - A CodeBuild project will be used as a managed build step to: + - Build Docker images from application repositories. + - Push images to the ECR repository created by `core/ecr`. + - CodeBuild will be triggered via GitHub Actions or future CI workflows using IAM roles instead of long-lived credentials. + +- **GitHub OIDC (federated IAM access)** + - `core/github-oidc` module defines: + - An IAM OIDC provider for `token.actions.githubusercontent.com`. + - An IAM role that can be assumed only by specific GitHub repositories/branches (e.g. `repo:/:ref:refs/heads/main`). + - This role will grant least-privilege access to: + - Read/write the Terraform remote state in S3/DynamoDB. + - Push images to ECR. + - Interact with CodeBuild when needed. + - This removes the need for static AWS keys in GitHub and aligns with AWS recommended security practices. --- @@ -21,7 +59,10 @@ Developer │ ├── infra-terraform │ ├── S3 bucket (Terraform backend) -│ └── DynamoDB table (state lock) +│ ├── DynamoDB table (Terraform state lock) +│ ├── AWS Secrets Manager (app secrets skeleton) +│ ├── ECR repository (container images per env) +│ └── IAM + OIDC role (GitHub Actions / CI access) │ ├── cluster-gitops │ ├── Kind cluster (shopstack) @@ -76,29 +117,36 @@ Results are saved to repeat.log. ```plaintext chmod 600 ~/.kube/config ``` -Docker daemon restricted to local use. -Terraform state secured in private AWS S3 bucket with DynamoDB locking. + - Terraform state stored in a private AWS S3 bucket with DynamoDB locking. + - GitHub CI uses federated IAM access via OIDC instead of static AWS credentials (infra v1 scope). --- ## 🧩 **Future Improvements** - - Add CI/CD pipeline for infrastructure changes. - - Integrate EKS managed cluster for cloud testing. - - Enable security scanning tools (Trivy, kube-bench). - - Automate bootstrap across all repositories with a unified Makefile. + - Add CI/CD pipeline for infrastructurechanges using GitHub Actions + OIDC. + - Integrate EKS managed cluster for cloud testing. + - Enable additional security scanning tools (Trivy, kube-bench, tfsec/Trivy for Terraform). + - Automate bootstrap across all repositories with a unified Makefile and shared scripts. --- ## 🗂️ **Folder Structure** ```bash infra-terraform/ +├── core/ +│ ├── backend/ # S3 + DynamoDB for Terraform remote state +│ ├── vpc/ # Experimental VPC module (not used in infra v1) +│ ├── github-oidc/ # IAM OIDC provider + role for GitHub Actions (planned) +│ ├── ecr/ # ECR repository definitions (planned) +│ └── secrets/ # Secrets Manager layout (planned) ├── envs/ │ └── dev/ -│ ├── backend.tf -│ ├── main.tf +│ ├── backend.tf # Backend configuration using S3/DynamoDB +│ ├── main.tf # Environment stack (modules wiring) +│ ├── outputs.tf │ └── versions.tf -├── .github/ -│ └── workflows/terraform-ci.yml +├── talos/ # Talos cluster configuration files (local cluster) +├── backend/ # Local bootstrap state (not used in normal flows) ├── Makefile └── docs/ └── ARCHITECTURE.md