Skip to content

Commit 04b417f

Browse files
committed
Terraform Cloud workspace management bootstrap and layer reorganization
1 parent 12e81be commit 04b417f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+434
-8
lines changed

README.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ This project demonstrates a FastAPI application deployed on AWS EKS with compreh
66

77
The infrastructure is organized in layers:
88

9-
- `0_ipam` - IP address management
10-
- `1_base` - Base infrastructure (EKS, VPC, OpenSearch)
11-
- `2_argo` - ArgoCD deployment
12-
- `3_kubernetes_addons` - Additional Kubernetes components
9+
- `0_tfc_bootstrap` - Terraform Cloud workspace management
10+
- `1_ipam` - IP address management (global, run once)
11+
- `2_base` - Base infrastructure (EKS, VPC, OpenSearch)
12+
- `3_argo` - ArgoCD deployment
13+
- `4_kubernetes_addons` - Additional Kubernetes components
1314

1415

1516

@@ -21,7 +22,8 @@ The project is organized into two main directories: `app` and `infra`.
2122
- `.venv/`: A virtual environment for managing Python dependencies locally.
2223

2324
- **`infra/`**: This directory holds the Infrastructure as Code (IaC) definitions using Terraform. The infrastructure is logically separated into layers, with each layer in its own directory.
24-
- `0_ipam/`: Manages the VPC IP address space.
25-
- `1_base/`: Defines the foundational cloud infrastructure, including the VPC and EKS cluster.
26-
- `2_argo/`: Sets up ArgoCD for GitOps-based continuous deployment.
27-
- `3_kubernetes_addons/`: Manages Kubernetes add-ons like external-secrets for secret management.
25+
- `0_tfc_bootstrap/`: Creates and manages Terraform Cloud workspaces, variable sets, and team access controls.
26+
- `1_ipam/`: Manages the VPC IP address space (global, run once).
27+
- `2_base/`: Defines the foundational cloud infrastructure, including the VPC and EKS cluster.
28+
- `3_argo/`: Sets up ArgoCD for GitOps-based continuous deployment.
29+
- `4_kubernetes_addons/`: Manages Kubernetes add-ons like external-secrets for secret management.

infra/0_tfc_bootstrap/README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Terraform Cloud Bootstrap
2+
3+
This module manages Terraform Cloud workspaces and configuration for the hello-fastapi-k8s project.
4+
5+
## Overview
6+
7+
This creates a complete Terraform Cloud setup including:
8+
- Organization project
9+
- Workspaces for each layer and environment
10+
- Variable sets for AWS credentials and common configurations
11+
- Run triggers for dependent workspaces
12+
- Team access controls
13+
14+
## Prerequisites
15+
16+
1. Terraform Cloud account and organization
17+
2. GitHub OAuth connection configured in TFC
18+
3. AWS credentials for TFC to use
19+
20+
## Usage
21+
22+
1. First, create the bootstrap workspace manually or via CLI:
23+
```bash
24+
cd infra/0_tfc_bootstrap
25+
terraform login
26+
terraform workspace new tfc-bootstrap
27+
```
28+
29+
2. Configure variables:
30+
```bash
31+
# Required variables
32+
export TF_VAR_tfc_organization="your-org"
33+
export TF_VAR_aws_access_key_id="AKIA..."
34+
export TF_VAR_aws_secret_access_key="secret..."
35+
export TF_VAR_github_repository="yourusername/hello-flask-k8s"
36+
```
37+
38+
3. Run terraform:
39+
```bash
40+
terraform init
41+
terraform plan
42+
terraform apply
43+
```
44+
45+
## Workspace Structure
46+
47+
The following workspaces will be created:
48+
49+
- `ipam-global` - IP Address Management (shared across all environments)
50+
- `base-{dev,staging,prod}` - Base infrastructure (VPC, EKS)
51+
- `argo-{dev,staging,prod}` - ArgoCD deployment
52+
- `addons-{dev,staging,prod}` - Kubernetes addons
53+
54+
## Features
55+
56+
- **Auto-apply**: Enabled for dev workspaces only
57+
- **Run triggers**: Dependent workspaces trigger automatically
58+
- **Branch protection**:
59+
- Dev/staging workspaces use respective branches
60+
- Prod workspaces use main branch
61+
- **Access control**: Developers have write access to dev/staging, plan-only for prod
62+
63+
## Customization
64+
65+
Edit `main.tf` to:
66+
- Add more layers or environments
67+
- Change auto-apply settings
68+
- Modify team permissions
69+
- Add notification channels (Slack, email, webhooks)

infra/0_tfc_bootstrap/data.tf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Data source for current organization
2+
data "tfe_organization" "main" {
3+
name = var.tfc_organization
4+
}
5+
6+
# GitHub OAuth Client
7+
data "tfe_oauth_client" "github" {
8+
organization = data.tfe_organization.main.name
9+
service_provider = "github"
10+
name = var.github_oauth_client_name
11+
}

infra/0_tfc_bootstrap/locals.tf

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
locals {
2+
environments = ["dev", "staging", "prod"]
3+
4+
# Layer definitions with dependencies
5+
layers = {
6+
base = {
7+
path = "infra/2_base"
8+
depends_on = ["ipam-global"]
9+
auto_apply = {
10+
dev = true
11+
staging = false
12+
prod = false
13+
}
14+
}
15+
argo = {
16+
path = "infra/3_argo"
17+
depends_on = ["base"]
18+
auto_apply = {
19+
dev = true
20+
staging = false
21+
prod = false
22+
}
23+
}
24+
addons = {
25+
path = "infra/4_kubernetes_addons"
26+
depends_on = ["base", "argo"]
27+
auto_apply = {
28+
dev = true
29+
staging = false
30+
prod = false
31+
}
32+
}
33+
}
34+
35+
# Flatten workspace configurations
36+
workspaces = flatten([
37+
for layer_name, layer in local.layers : [
38+
for env in local.environments : {
39+
name = "${layer_name}-${env}"
40+
layer = layer_name
41+
environment = env
42+
path = layer.path
43+
depends_on = layer.depends_on
44+
auto_apply = layer.auto_apply[env]
45+
}
46+
]
47+
])
48+
49+
# Create workspace map for easy lookup
50+
workspace_map = {
51+
for ws in local.workspaces : ws.name => ws
52+
}
53+
}

infra/0_tfc_bootstrap/main.tf

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Main configuration file for Terraform Cloud bootstrap
2+
# This module creates and manages all Terraform Cloud workspaces,
3+
# variable sets, teams, and access controls for the hello-fastapi-k8s project.
4+
5+
# All configuration is split into logical files:
6+
# - versions.tf: Terraform and provider version constraints
7+
# - providers.tf: Provider configurations
8+
# - data.tf: Data sources
9+
# - locals.tf: Local values and computed configurations
10+
# - project.tf: TFC project configuration
11+
# - variable_sets.tf: Variable sets and variables
12+
# - workspaces.tf: Workspace definitions
13+
# - workspace_variables.tf: Workspace-specific variables
14+
# - run_triggers.tf: Dependencies between workspaces
15+
# - teams.tf: Team and access control configuration
16+
# - notifications.tf: Notification settings (placeholder)
17+
# - variables.tf: Input variables
18+
# - outputs.tf: Output values
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Notifications configuration placeholder
2+
# Future enhancements can add Slack, email, or webhook notifications here

infra/0_tfc_bootstrap/outputs.tf

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
output "workspace_ids" {
2+
description = "Map of workspace names to their IDs"
3+
value = merge(
4+
{ "ipam-global" = tfe_workspace.ipam.id },
5+
{ for k, v in tfe_workspace.main : k => v.id }
6+
)
7+
}
8+
9+
output "workspace_urls" {
10+
description = "URLs to access each workspace"
11+
value = merge(
12+
{ "ipam-global" = "https://app.terraform.io/app/${var.tfc_organization}/workspaces/${tfe_workspace.ipam.name}" },
13+
{ for k, v in tfe_workspace.main : k => "https://app.terraform.io/app/${var.tfc_organization}/workspaces/${v.name}" }
14+
)
15+
}
16+
17+
output "project_id" {
18+
description = "The ID of the Terraform Cloud project"
19+
value = tfe_project.hello_fastapi.id
20+
}
21+
22+
output "variable_set_ids" {
23+
description = "IDs of the variable sets"
24+
value = {
25+
aws_credentials = tfe_variable_set.aws_credentials.id
26+
common_tags = tfe_variable_set.common_tags.id
27+
environments = { for k, v in tfe_variable_set.env : k => v.id }
28+
}
29+
}

infra/0_tfc_bootstrap/project.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Create project for better organization
2+
resource "tfe_project" "hello_fastapi" {
3+
organization = data.tfe_organization.main.name
4+
name = "hello-fastapi-k8s"
5+
description = "FastAPI application on Kubernetes - DevOps showcase project"
6+
}

infra/0_tfc_bootstrap/providers.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
provider "tfe" {
2+
# TFE_TOKEN environment variable or terraform login
3+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Run triggers for dependencies
2+
resource "tfe_run_trigger" "dependencies" {
3+
for_each = {
4+
for ws in local.workspaces : ws.name => ws
5+
if length(ws.depends_on) > 0
6+
}
7+
8+
workspace_id = tfe_workspace.main[each.key].id
9+
sourceable_id = each.value.depends_on[0] == "ipam-global" ?
10+
tfe_workspace.ipam.id :
11+
tfe_workspace.main["${each.value.depends_on[0]}-${each.value.environment}"].id
12+
}

0 commit comments

Comments
 (0)