project-plan-v2.md - GCP Deployment Plan with OpenTofu
CODITECT Document Management System - Production Deployment
Version: 2.0.0 Created: 2025-12-28 Status: Ready for Execution Owner: Platform Engineering Team
Workflow Steps
- Initialize - Set up the environment
- Configure - Apply settings
- Execute - Run the process
- Validate - Check results
- Complete - Finalize workflow
Executive Summary
This document outlines the complete deployment plan for CODITECT DMS to Google Cloud Platform using OpenTofu (open-source Terraform). The deployment follows Infrastructure as Code (IaC) best practices with modular, reusable components.
Deployment Targets
| Environment | Project ID | Region | Purpose |
|---|---|---|---|
| Development | coditect-dev | us-central1 | Developer testing |
| Staging | coditect-staging | us-central1 | Pre-production validation |
| Production | coditect-prod | us-central1 | Live customer traffic |
Infrastructure Cost Estimates
| Environment | Monthly Cost | Components |
|---|---|---|
| Development | ~$150 | Minimal resources, preemptible nodes |
| Staging | ~$500 | Moderate resources, spot instances |
| Production | ~$2,500 | Full HA, autoscaling, backups |
Phase 1: Prerequisites & Setup
1.1 Required Tools Installation
# Install OpenTofu (macOS)
brew install opentofu
# Install Google Cloud SDK
brew install google-cloud-sdk
# Install kubectl
brew install kubectl
# Install Helm
brew install helm
# Verify installations
tofu version # >= 1.6.0
gcloud version # >= 450.0.0
kubectl version # >= 1.28.0
helm version # >= 3.12.0
1.2 GCP Project Setup
# Authenticate with GCP
gcloud auth login
gcloud auth application-default login
# Create projects (if needed)
gcloud projects create coditect-dev --name="CODITECT Dev"
gcloud projects create coditect-staging --name="CODITECT Staging"
gcloud projects create coditect-prod --name="CODITECT Production"
# Link billing account
gcloud billing projects link coditect-dev --billing-account=BILLING_ACCOUNT_ID
gcloud billing projects link coditect-staging --billing-account=BILLING_ACCOUNT_ID
gcloud billing projects link coditect-prod --billing-account=BILLING_ACCOUNT_ID
1.3 Enable Required APIs
# For each project
for PROJECT in coditect-dev coditect-staging coditect-prod; do
gcloud services enable \
--project=$PROJECT \
container.googleapis.com \
sqladmin.googleapis.com \
redis.googleapis.com \
secretmanager.googleapis.com \
cloudarmor.googleapis.com \
monitoring.googleapis.com \
logging.googleapis.com \
compute.googleapis.com \
servicenetworking.googleapis.com \
cloudresourcemanager.googleapis.com \
iam.googleapis.com \
storage.googleapis.com \
aiplatform.googleapis.com \
pubsub.googleapis.com
done
1.4 Create Terraform State Bucket
# Create state bucket for each environment
for PROJECT in coditect-dev coditect-staging coditect-prod; do
gsutil mb -p $PROJECT -l us-central1 gs://${PROJECT}-terraform-state
gsutil versioning set on gs://${PROJECT}-terraform-state
done
Phase 2: Infrastructure Deployment
2.1 Directory Structure
infrastructure/opentofu/
├── main.tf # Main configuration
├── variables.tf # Input variables
├── outputs.tf # Output values
├── modules/
│ ├── networking/ # VPC, subnets, firewall
│ ├── gke/ # Kubernetes cluster
│ ├── cloudsql/ # PostgreSQL with pgvector
│ ├── redis/ # Memorystore Redis
│ ├── iam/ # Service accounts, roles
│ ├── secrets/ # Secret Manager
│ ├── storage/ # Cloud Storage buckets
│ └── monitoring/ # Alerts, dashboards
└── environments/
├── dev/
│ └── terraform.tfvars
├── staging/
│ └── terraform.tfvars
└── prod/
└── terraform.tfvars
2.2 Deployment Order
Infrastructure must be deployed in this order due to dependencies:
- Networking → VPC, subnets, NAT, firewall
- IAM → Service accounts, roles
- Secrets → Secret Manager secrets
- Cloud SQL → PostgreSQL database
- Redis → Memorystore cache
- GKE → Kubernetes cluster
- Storage → GCS buckets
- Monitoring → Alerts, dashboards
2.3 Development Deployment
cd infrastructure/opentofu
# Initialize OpenTofu
tofu init -backend-config="bucket=coditect-dev-terraform-state"
# Plan deployment
tofu plan -var-file=environments/dev/terraform.tfvars -out=dev.tfplan
# Review plan carefully, then apply
tofu apply dev.tfplan
# Verify outputs
tofu output
2.4 Staging Deployment
# Reinitialize for staging
tofu init -backend-config="bucket=coditect-staging-terraform-state" -reconfigure
# Plan and apply
tofu plan -var-file=environments/staging/terraform.tfvars -out=staging.tfplan
tofu apply staging.tfplan
2.5 Production Deployment
# Reinitialize for production
tofu init -backend-config="bucket=coditect-prod-terraform-state" -reconfigure
# Plan deployment
tofu plan -var-file=environments/prod/terraform.tfvars -out=prod.tfplan
# CRITICAL: Review plan with team before applying
# Get approval from Platform Lead and Security
tofu apply prod.tfplan
Phase 3: Application Deployment
3.1 Configure kubectl
# Get GKE credentials
gcloud container clusters get-credentials coditect-dms-prod-cluster \
--region us-central1 \
--project coditect-prod
# Verify connection
kubectl get nodes
kubectl get namespaces
3.2 Create Kubernetes Namespace
kubectl create namespace coditect-dms
kubectl label namespace coditect-dms \
app=coditect-dms \
environment=prod
3.3 Create Kubernetes Secrets
# Get secrets from Secret Manager
export DATABASE_URL=$(gcloud secrets versions access latest \
--secret=coditect-dms-prod-database-url \
--project=coditect-prod)
export JWT_SECRET=$(gcloud secrets versions access latest \
--secret=coditect-dms-prod-jwt-secret \
--project=coditect-prod)
export REDIS_URL=$(gcloud secrets versions access latest \
--secret=coditect-dms-prod-redis-url \
--project=coditect-prod)
# Create Kubernetes secret
kubectl create secret generic dms-secrets \
--namespace=coditect-dms \
--from-literal=database-url="$DATABASE_URL" \
--from-literal=jwt-secret="$JWT_SECRET" \
--from-literal=redis-url="$REDIS_URL"
3.4 Build and Push Docker Images
# Configure Docker for GCR
gcloud auth configure-docker gcr.io
# Build API image
docker build -t gcr.io/coditect-prod/coditect-dms-api:v1.0.0 \
-f Dockerfile.api .
# Push to registry
docker push gcr.io/coditect-prod/coditect-dms-api:v1.0.0
3.5 Deploy Application
# Apply Kubernetes manifests
kubectl apply -f deploy/kubernetes/deployment.yaml
kubectl apply -f deploy/kubernetes/service.yaml
kubectl apply -f deploy/kubernetes/ingress.yaml
kubectl apply -f deploy/kubernetes/monitoring.yaml
# Wait for deployment
kubectl rollout status deployment/coditect-dms-api -n coditect-dms
# Verify pods
kubectl get pods -n coditect-dms
Phase 4: Database Setup
4.1 Connect to Cloud SQL
# Start Cloud SQL Proxy
cloud_sql_proxy -instances=coditect-prod:us-central1:coditect-dms-db-xxxx=tcp:5432 &
# Connect with psql
PGPASSWORD=$(gcloud secrets versions access latest \
--secret=coditect-dms-prod-db-admin-password) \
psql -h localhost -U dms_admin -d coditect_dms
4.2 Enable pgvector Extension
-- Enable pgvector for semantic search
CREATE EXTENSION IF NOT EXISTS vector;
-- Verify extension
SELECT * FROM pg_extension WHERE extname = 'vector';
4.3 Run Database Migrations
# Set database URL
export DATABASE_URL=$(gcloud secrets versions access latest \
--secret=coditect-dms-prod-database-url)
# Run Alembic migrations
alembic upgrade head
# Verify migrations
alembic current
Phase 5: DNS & SSL Configuration
5.1 Reserve Static IP (already done by OpenTofu)
# Verify static IP
gcloud compute addresses describe coditect-dms-prod-lb-ip --global
5.2 Configure Cloud DNS
# Create DNS zone (if not exists)
gcloud dns managed-zones create coditect-zone \
--dns-name="coditect.ai." \
--description="CODITECT DNS zone"
# Add A record for API
gcloud dns record-sets transaction start --zone=coditect-zone
gcloud dns record-sets transaction add \
--zone=coditect-zone \
--name="dms-api.coditect.ai." \
--ttl=300 \
--type=A \
$(tofu output -raw load_balancer_ip)
gcloud dns record-sets transaction execute --zone=coditect-zone
5.3 SSL Certificate
GKE Managed Certificates (configured in ingress.yaml) automatically provision Let's Encrypt certificates.
# Check certificate status
kubectl get managedcertificate -n coditect-dms
Phase 6: Monitoring & Alerting
6.1 Verify Alert Policies
# List alert policies
gcloud alpha monitoring policies list --project=coditect-prod
6.2 Access Grafana Dashboard
# Port forward to Grafana (if using kube-prometheus-stack)
kubectl port-forward svc/monitoring-grafana 3000:80 -n monitoring
# Open http://localhost:3000
# Default credentials: admin / prom-operator
6.3 Test Uptime Checks
# Verify health endpoint
curl -I https://dms-api.coditect.ai/health
curl -I https://dms-api.coditect.ai/health/ready
Phase 7: Post-Deployment Validation
7.1 Smoke Tests
# Health check
curl https://dms-api.coditect.ai/health
# API documentation
curl https://dms-api.coditect.ai/docs
# Create test tenant
curl -X POST https://dms-api.coditect.ai/api/v1/tenants \
-H "Content-Type: application/json" \
-d '{"name": "Test Tenant", "email": "test@example.com"}'
7.2 Load Testing
# Install k6
brew install k6
# Run load test
k6 run tests/load/api-load-test.js
7.3 Security Scan
# Run OWASP ZAP scan
docker run -t owasp/zap2docker-stable zap-baseline.py \
-t https://dms-api.coditect.ai
Rollback Procedures
Application Rollback
# Rollback to previous deployment
kubectl rollout undo deployment/coditect-dms-api -n coditect-dms
# Rollback to specific revision
kubectl rollout undo deployment/coditect-dms-api -n coditect-dms --to-revision=5
Infrastructure Rollback
# View state history
tofu state list
# Rollback infrastructure (DANGEROUS - use with caution)
tofu apply -target=module.specific_module -var-file=environments/prod/terraform.tfvars
Database Rollback
# Alembic downgrade
alembic downgrade -1
# Or restore from backup
gcloud sql backups restore BACKUP_ID \
--restore-instance=coditect-dms-db-xxxx \
--backup-instance=coditect-dms-db-xxxx
Maintenance Procedures
Scaling
# Scale API pods
kubectl scale deployment coditect-dms-api --replicas=10 -n coditect-dms
# Scale workers
kubectl scale deployment dms-worker --replicas=5 -n coditect-dms
# Update HPA
kubectl patch hpa dms-api-hpa -n coditect-dms \
-p '{"spec":{"maxReplicas":30}}'
Updates
# Update container image
kubectl set image deployment/coditect-dms-api \
api=gcr.io/coditect-prod/coditect-dms-api:v1.1.0 \
-n coditect-dms
# Monitor rollout
kubectl rollout status deployment/coditect-dms-api -n coditect-dms
Security Checklist
- All secrets stored in Secret Manager (not in code)
- Workload Identity enabled for pod authentication
- Network policies restrict pod-to-pod communication
- Cloud Armor WAF rules active
- Private GKE cluster with no public node IPs
- Cloud SQL accessible only via private IP
- Redis accessible only via private IP
- TLS 1.3 enforced on load balancer
- Binary Authorization enabled (production)
- Audit logging enabled
Contacts
| Role | Name | |
|---|---|---|
| Platform Lead | TBD | platform@az1.ai |
| Security Lead | TBD | security@az1.ai |
| On-Call | PagerDuty | oncall@az1.ai |
| CTO | Hal Casteel | 1@az1.ai |
Appendix A: OpenTofu Module Reference
| Module | Purpose | Key Resources |
|---|---|---|
| networking | VPC infrastructure | VPC, subnets, NAT, firewall, Cloud Armor |
| gke | Kubernetes cluster | GKE cluster, node pools, autoscaling |
| cloudsql | PostgreSQL database | Cloud SQL instance, users, secrets |
| redis | Redis cache | Memorystore instance, auth secrets |
| iam | Identity management | Service accounts, IAM bindings |
| secrets | Secret management | JWT, API keys, encryption keys |
| storage | Object storage | Documents, backups, static assets |
| monitoring | Observability | Alerts, dashboards, uptime checks |
Appendix B: Environment Comparison
| Resource | Dev | Staging | Prod |
|---|---|---|---|
| GKE nodes | 1 (e2-medium) | 2 (e2-standard-2) | 3-20 (n2-standard-4) |
| Cloud SQL | db-f1-micro | db-custom-2-8192 | db-custom-4-16384 |
| Redis | 1GB Basic | 2GB Basic | 5GB HA |
| Preemptible | Yes | Yes | No |
| HA | No | No | Yes |
| Backups | 7 days | 14 days | 30 days |
| Cloud Armor | No | Yes | Yes |
Document Version: 2.0.0 Last Updated: 2025-12-28 Next Review: 2026-01-28