Terraform Infrastructure as Code
Helix Platform AWS Infrastructure
Overview
This directory contains all Terraform configurations for deploying Helix platform infrastructure to AWS. The infrastructure is organized using modules for reusability and environment-specific configurations for dev, staging, and production.
Infrastructure Components
- Networking - VPC, subnets, security groups
- ECS Cluster - Container orchestration with Fargate
- Database - RDS PostgreSQL (3-tier architecture)
- Redis - ElastiCache for queues and caching
- S3 - Object storage for files and reports
- IAM - Roles and policies for service access
- Secrets - Secrets Manager for credential management
Directory Structure
terraform/
├── main.tf # Root module orchestration
├── variables.tf # Global variable definitions
├── outputs.tf # Root-level outputs
├── terraform.tfvars.example # Example variable values
├── .gitignore # Exclude sensitive files
├── README.md # This file
│
├── global/
│ ├── provider.tf # AWS provider configuration
│ └── backend.tf # State backend configuration
│
├── environments/
│ ├── dev/ # Development environment
│ │ └── main.tf
│ ├── staging/ # Staging environment
│ │ └── main.tf
│ └── prod/ # Production environment
│ └── main.tf
│
└── modules/
├── networking/ # VPC, subnets, security groups
├── ecs-cluster/ # ECS/Fargate configuration
├── database/ # RDS PostgreSQL
├── redis/ # ElastiCache Redis
├── s3/ # S3 buckets
├── iam/ # IAM roles and policies
└── secrets/ # Secrets Manager
Prerequisites
Required Tools
- Terraform >= 1.5.0
- AWS CLI >= 2.0
- jq (for parsing outputs)
Install Terraform:
# macOS
brew install terraform
# Linux
wget https://releases.hashicorp.com/terraform/1.6.0/terraform_1.6.0_linux_amd64.zip
unzip terraform_1.6.0_linux_amd64.zip
sudo mv terraform /usr/local/bin/
Verify installation:
terraform --version
AWS Credentials
Configure AWS credentials using one of these methods:
Option 1: AWS CLI
aws configure
Option 2: Environment Variables
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
export AWS_DEFAULT_REGION="us-east-1"
Option 3: AWS Profile
export AWS_PROFILE="helix-dev"
Quick Start
1. Initialize Terraform
cd terraform
# Initialize Terraform (downloads providers, sets up backend)
terraform init
2. Create Variable File
# Copy example and fill in values
cp terraform.tfvars.example terraform.tfvars
# Edit with your values
nano terraform.tfvars
3. Plan Infrastructure
# See what will be created
terraform plan
# Save plan to file
terraform plan -out=tfplan
4. Apply Infrastructure
# Apply the plan
terraform apply tfplan
# Or apply directly (will prompt for confirmation)
terraform apply
5. Verify Deployment
# Show current state
terraform show
# List all resources
terraform state list
# Get specific output
terraform output vpc_id
Working with Environments
Environment-Specific Deployments
Each environment (dev, staging, prod) has its own configuration:
# Deploy to development
cd environments/dev
terraform init
terraform plan
terraform apply
# Deploy to staging
cd environments/staging
terraform init
terraform plan
terraform apply
# Deploy to production
cd environments/prod
terraform init
terraform plan
terraform apply
Environment Differences
| Resource | Dev | Staging | Production |
|---|---|---|---|
| Multi-AZ | No | Yes | Yes |
| DB Instance | t3.small | t3.medium | r5.large |
| Redis Nodes | 1 | 2 | 3 |
| Deletion Protection | No | Yes | Yes |
| Backup Retention | 7 days | 7 days | 30 days |
State Management
Remote State Backend
Terraform state is stored in S3 with DynamoDB locking for team collaboration.
Setup Backend (One-Time):
# 1. Create S3 bucket for state
aws s3 mb s3://helix-terraform-state --region us-east-1
# 2. Enable versioning
aws s3api put-bucket-versioning \
--bucket helix-terraform-state \
--versioning-configuration Status=Enabled
# 3. Create DynamoDB table for locking
aws dynamodb create-table \
--table-name helix-terraform-locks \
--attribute-definitions AttributeName=LockID,AttributeType=S \
--key-schema AttributeName=LockID,KeyType=HASH \
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
--region us-east-1
# 4. Uncomment backend configuration in global/backend.tf
# 5. Migrate to remote backend
terraform init -reconfigure
State Commands
# List resources in state
terraform state list
# Show resource details
terraform state show aws_vpc.main
# Move resource in state
terraform state mv aws_instance.old aws_instance.new
# Remove resource from state (doesn't delete resource)
terraform state rm aws_instance.example
# Pull latest state
terraform state pull > terraform.tfstate.backup
Module Development
Adding a New Module
- Create module directory:
mkdir -p modules/my-module
cd modules/my-module
- Create required files:
touch main.tf variables.tf outputs.tf
- Define module structure:
# main.tf
resource "aws_example" "main" {
# Resource configuration
}
# variables.tf
variable "example_var" {
description = "Example variable"
type = string
}
# outputs.tf
output "example_output" {
value = aws_example.main.id
}
- Use module in root:
# terraform/main.tf
module "my_module" {
source = "./modules/my-module"
example_var = "value"
}
Common Workflows
Deploying New Services
# 1. Update module code
nano modules/ecs-cluster/main.tf
# 2. Plan changes
terraform plan -out=tfplan
# 3. Review changes
terraform show tfplan
# 4. Apply if satisfied
terraform apply tfplan
Updating Existing Resources
# 1. Modify configuration
nano terraform.tfvars
# 2. Plan and apply
terraform plan
terraform apply
Destroying Resources
# Destroy specific resource
terraform destroy -target=aws_instance.example
# Destroy everything (DANGEROUS!)
terraform destroy
# Production safety: Never destroy without explicit approval
Database Architecture in Terraform
3-Tier Database Strategy
The Helix platform uses a 3-tier database architecture with separate databases per tenant:
Tier 1 & 2 (Central):
helix_central- Platform metadata (NO PII)tenant_{uuid}_shared- Per-tenant shared data (WITH PII)
Tier 3 (Service-Specific):
tenant_{uuid}_kira- KIRA service databasetenant_{uuid}_vera- VERA service databasetenant_{uuid}_cleverscreen- CleverScreen service database
Deployment Flexibility
Local Development:
# All databases on single PostgreSQL instance
resource "aws_db_instance" "central" {
identifier = "helix-dev"
# Hosts: helix_central, tenant_*_shared, tenant_*_kira, etc.
}
Production:
# Separate RDS instances per tier
resource "aws_db_instance" "central" {
identifier = "helix-central"
# Hosts: helix_central only
}
resource "aws_db_instance" "tenant_tier2" {
identifier = "helix-tenant-shared"
# Hosts: tenant_*_shared databases
}
resource "aws_db_instance" "kira_tier3" {
identifier = "helix-kira"
# Hosts: tenant_*_kira databases
}
Connection strings are dynamically resolved per tenant via middleware.
Security Best Practices
Sensitive Data
❌ NEVER commit to Git:
terraform.tfvars(contains real values)*.tfstatefiles (contains secrets)- AWS credentials
- Database passwords
✅ DO commit:
terraform.tfvars.example(template with placeholders).tffiles (infrastructure code).gitignore(excludes sensitive files)
Secrets Management
# WRONG - Hardcoded secret
resource "aws_db_instance" "main" {
password = "hardcoded_password" # ❌ Never do this
}
# CORRECT - Reference Secrets Manager
resource "aws_db_instance" "main" {
password = data.aws_secretsmanager_secret_version.db.secret_string
}
State File Security
# Enable encryption for state bucket
resource "aws_s3_bucket_server_side_encryption_configuration" "terraform_state" {
bucket = aws_s3_bucket.terraform_state.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
Troubleshooting
Terraform Init Fails
# Clear cache
rm -rf .terraform
rm .terraform.lock.hcl
# Re-initialize
terraform init
State Lock Error
# If state is locked from crashed operation
terraform force-unlock LOCK_ID
# Get lock ID from error message
Plan Shows Unexpected Changes
# Refresh state to match reality
terraform refresh
# Compare state with real infrastructure
terraform plan -refresh-only
Module Not Found
# Ensure module path is correct
terraform init
# Check module source
terraform get -update
Validation and Formatting
Format Code
# Format all .tf files
terraform fmt -recursive
# Check formatting without changes
terraform fmt -check
Validate Configuration
# Validate syntax and configuration
terraform validate
# Validate with variable file
terraform validate -var-file=terraform.tfvars
Lint Configuration
# Install tflint
brew install tflint
# Run linter
tflint
Advanced Topics
Importing Existing Resources
# Import existing AWS resource into Terraform state
terraform import aws_vpc.main vpc-12345678
# Verify import
terraform plan
Targeting Specific Resources
# Plan specific resource
terraform plan -target=module.database
# Apply specific resource
terraform apply -target=module.networking
Workspaces
# List workspaces
terraform workspace list
# Create workspace
terraform workspace new staging
# Switch workspace
terraform workspace select production
CI/CD Integration
GitHub Actions Example
name: Terraform Deploy
on:
push:
branches: [main]
paths:
- 'terraform/**'
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.6.0
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Terraform Init
run: terraform init
- name: Terraform Plan
run: terraform plan -out=tfplan
- name: Terraform Apply
if: github.ref == 'refs/heads/main'
run: terraform apply -auto-approve tfplan
Migration and Upgrades
Upgrading Providers
# Update provider versions
terraform init -upgrade
# Review changes
terraform plan
State Migration
# Migrate from local to remote backend
terraform init -migrate-state
# Migrate between backends
terraform init -reconfigure
Cost Estimation
Using Infracost
# Install infracost
brew install infracost
# Generate cost estimate
infracost breakdown --path .
# Compare changes
terraform plan -out=tfplan
infracost diff --path tfplan
Reference Documentation
- Helix Architecture: See Build Architecture
- Database Architecture: See Database & Prisma
- Docker Setup: See Docker Setup
- Deployment Guide: See Deployment Guide
Support
For infrastructure questions, contact the Platform Team.
Last Updated: 2025-10-21
Terraform Version: >= 1.5.0
AWS Provider Version: ~> 5.0