A production-ready deployment of Supabase on AWS using CDK for Terraform (CDKTF) in Python. This solution provides a highly automated, secure, and scalable infrastructure for running Supabase in your AWS environment.
This deployment successfully implements all required components for the DevOps take-home project:
- β Network: Secure and isolated VPC with public/private subnets, NAT Gateways, and proper routing
- β Kubernetes: Amazon EKS deployed in private subnets, spanning 2+ availability zones for high availability
- β Managed Database: Aurora PostgreSQL in private subnets with high availability and automated backups
- β Object Storage: S3 bucket with encryption, versioning, and proper IAM access policies
- β Secrets Management: AWS Secrets Manager storing all sensitive configurations (JWT secrets, DB credentials, API keys)
- β Network Access Controls: Security groups with least privilege (EKS control plane, nodes, RDS isolation)
- β IAM Least Privilege: Service-specific IRSA roles with minimal required permissions
- β Kubernetes NetworkPolicies: Pod-to-pod communication restrictions implemented
- β External Secrets Operator: Secure injection of AWS Secrets Manager secrets into Kubernetes using IRSA authentication
- β Horizontal Pod Autoscaler: Auto-scaling for Auth, REST, Storage, and Kong components with CPU/memory thresholds
- β AWS Load Balancer Controller: ALB ingress with SSL termination and health checks
- β Cluster Autoscaler: Automatic EKS node scaling based on pod demands with Graviton2 instances
- β Multi-AZ Deployment: Infrastructure distributed across multiple availability zones for high availability
- β Metrics Server: Kubernetes metrics collection for HPA functionality
- β Persistent Storage: GP3 EBS volumes with encryption and backup strategies
Status: All requirements successfully implemented and deployed! π
- π External Secrets Integration: Fully working AWS Secrets Manager integration with proper IRSA authentication
- π Horizontal Pod Autoscaler: All critical services now auto-scale based on CPU and memory usage
- π Metrics Server: Successfully deployed and providing real-time resource metrics
- π§ CDKTF Architecture: Complete infrastructure as code implementation with modular components
This deployment creates a comprehensive AWS infrastructure optimized for Supabase:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β AWS Cloud β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β VPC β β
β β β β
β β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β β
β β β Public β β Public β β Private β β β
β β β Subnet β β Subnet β β Subnet β β β
β β β (AZ-a) β β (AZ-b) β β (AZ-a) β β β
β β β β β β β β β β
β β β ββββββββββββ β β ββββββββββββ β β ββββββββββββ β β β
β β β β NAT β β β β NAT β β β β EKS β β β β
β β β β Gateway β β β β Gateway β β β β Nodes β β β β
β β β ββββββββββββ β β ββββββββββββ β β ββββββββββββ β β β
β β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β β
β β β β
β β ββββββββββββββββ ββββββββββββββββ β β
β β β Private β β Database β β β
β β β Subnet β β Subnet β β β
β β β (AZ-b) β β (AZ-a) β β β
β β β β β β β β
β β β ββββββββββββ β β ββββββββββββ β β β
β β β β EKS β β β β RDS β β β β
β β β β Nodes β β β βPostgreSQLβ β β β
β β β ββββββββββββ β β ββββββββββββ β β β
β β ββββββββββββββββ ββββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β External Services β β
β β β β
β β βββββββββββββββ βββββββββββββββ βββββββββββββββ β β
β β β S3 β β Secrets β β Route 53 β β β
β β β Storage β β Manager β β (DNS) β β β
β β βββββββββββββββ βββββββββββββββ βββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β EKS Cluster β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Ingress Layer β β
β β β β
β β βββββββββββββββ βββββββββββββββ β β
β β β AWS ALB ββββββββββββββββ Kong β β β
β β β Controller β β Gateway β β β
β β βββββββββββββββ βββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Application Layer β β
β β β β
β β βββββββββββββββ βββββββββββββββ βββββββββββββββ β β
β β β Studio β β Auth β β REST β β β
β β β (Dashboard) β β (GoTrue) β β (PostgREST) β β β
β β βββββββββββββββ βββββββββββββββ βββββββββββββββ β β
β β β β
β β βββββββββββββββ βββββββββββββββ βββββββββββββββ β β
β β β Storage β β Realtime β β Meta β β β
β β β API β β Server β β API β β β
β β βββββββββββββββ βββββββββββββββ βββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Infrastructure Layer β β
β β β β
β β βββββββββββββββ βββββββββββββββ βββββββββββββββ β β
β β β External β β Cluster β β HPA β β β
β β β Secrets β β Autoscaler β β Metrics β β β
β β βββββββββββββββ βββββββββββββββ βββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- CDKTF (Python): Modern IaC using familiar programming constructs
- Modular Architecture: Clean separation of concerns with reusable components
- Type Safety: Python type hints and validation throughout
- Multi-AZ Deployment: Resources distributed across 2 availability zones
- Auto Scaling: HPA for pods, Cluster Autoscaler for nodes
- Load Balancing: AWS Application Load Balancer with health checks
- Database HA: Aurora PostgreSQL with read replicas
- Network Isolation: Private subnets for all compute resources
- Secrets Management: AWS Secrets Manager with External Secrets Operator
- IAM Least Privilege: Service-specific roles with minimal permissions
- Encryption: At-rest and in-transit encryption throughout
- CloudWatch Integration: Native AWS monitoring and logging
- Performance Insights: Database performance monitoring
- Application Metrics: Built-in metrics for all Supabase components
- AWS CLI v2 - configured with appropriate credentials
- kubectl - Kubernetes command-line tool
- Helm 3 - Kubernetes package manager
- CDKTF CLI - CDK for Terraform
- Python 3.8+ - with pip
- AWS account with appropriate permissions
- Service quotas sufficient for EKS, RDS, and other services
- Domain name for SSL certificate (optional but recommended)
Your AWS credentials need permissions for:
- VPC and networking resources
- EKS cluster and node group management
- RDS cluster creation and management
- S3 bucket operations
- Secrets Manager operations
- IAM role and policy management
- CloudWatch and CloudFormation
- Familiarity: Python provides better developer experience than HCL
- Type Safety: Compile-time validation prevents common errors
- Modularity: Object-oriented design enables better code organization
- Testing: Unit testing infrastructure code with familiar tools
- Kubernetes Native: Supabase community charts are designed for K8s
- Flexibility: Better control over resource allocation and scaling
- Ecosystem: Rich ecosystem of operators and tools
- Portability: Can be migrated to other K8s platforms if needed
- High Availability: Built-in multi-AZ replication
- Performance: Better performance at scale
- Backup & Recovery: Continuous backup with point-in-time recovery
- Compatibility: Full PostgreSQL compatibility
git clone <repository-url>
cd supabase-aws-cdktfaws configure
# Enter your AWS credentials, region (us-west-2), and output format (json)./scripts/deploy.shThis will:
- Install Python dependencies
- Deploy AWS infrastructure (15-20 minutes)
- Configure kubectl for EKS
- Install essential Kubernetes components
- Configure External Secrets Operator
- Deploy Supabase with Helm
./scripts/verify.shThe CDKTF deployment creates the following AWS resources:
-
Networking
- VPC with public/private subnets across 2 AZs
- Internet Gateway and NAT Gateways for internet access
- Route tables and security groups
-
Compute
- EKS cluster with managed node groups
- Auto Scaling Groups with Graviton2 instances
-
Database
- Aurora PostgreSQL cluster with primary and replica instances
- Encrypted storage with automated backups
-
Storage
- S3 bucket with versioning and encryption
- Lifecycle policies for cost optimization
-
Security
- Secrets Manager for sensitive configuration
- IAM roles with least-privilege access
- Security groups with minimal required access
# Deploy infrastructure only
cdktf deploy supabase-aws --auto-approveAfter infrastructure deployment:
# Configure kubectl
aws eks update-kubeconfig --region us-west-2 --name supabase-eks
# Verify cluster access
kubectl cluster-info# Create namespace
kubectl create namespace supabase
# Install External Secrets Operator
helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets \
--namespace external-secrets-system \
--create-namespace \
--set installCRDs=true
# Install AWS Load Balancer Controller
kubectl apply -f k8s/aws-load-balancer-controller.yaml
# Install Cluster Autoscaler
kubectl apply -f k8s/cluster-autoscaler.yamlThe External Secrets Operator is automatically configured via CDKTF to pull secrets from AWS Secrets Manager:
# Verify External Secrets are working
kubectl get clustersecretstore aws-secrets-manager-cluster
kubectl get externalsecrets -n supabase
kubectl get secrets -n supabase
# Check specific secrets
kubectl get secret supabase-database-secret -n supabase -o yaml
kubectl get secret supabase-jwt-secret -n supabase -o yaml
kubectl get secret supabase-api-keys-secret -n supabase -o yamlThe deployment automatically creates and syncs the following secrets from AWS Secrets Manager:
supabase-database-secret- Database connection detailssupabase-jwt-secret- JWT authentication secretsupabase-api-keys-secret- API keys (anon, service role)supabase-storage-secret- S3 storage configurationsupabase-auth-secret- Auth service configuration
# Add Supabase Helm repository
helm repo add supabase https://supabase-community.github.io/supabase-kubernetes
# Deploy Supabase
helm install supabase supabase/supabase \
--namespace supabase \
--values k8s/values.yaml \
--timeout 15m# Check AWS resources
aws eks describe-cluster --name supabase-eks --query 'cluster.status'
aws rds describe-db-clusters --db-cluster-identifier supabase-postgres --query 'DBClusters[0].Status'
# Check Kubernetes cluster
kubectl get nodes
kubectl get pods -n supabase# Get Load Balancer URL
kubectl get ingress -n supabase
# Check HPA status
kubectl get hpa -n supabase
# Check External Secrets status
kubectl get externalsecrets -n supabase
kubectl get clustersecretstore aws-secrets-manager-cluster
# Test endpoints
curl -k https://<load-balancer-url>/health
curl -k https://<load-balancer-url>/rest/v1/# Run comprehensive verification
./scripts/verify.shThis script performs:
- Infrastructure validation
- Kubernetes cluster health check
- Metrics Server and HPA verification
- External secrets synchronization verification
- Supabase component status check
- Load balancer and ingress validation
- Auto-scaling functionality tests
- Smoke tests on API endpoints
After successful deployment:
- Supabase Studio:
https://<load-balancer-url>/studio - REST API:
https://<load-balancer-url>/rest/v1/ - Realtime:
wss://<load-balancer-url>/realtime/v1/websocket - Storage API:
https://<load-balancer-url>/storage/v1/ - Auth API:
https://<load-balancer-url>/auth/v1/
Key configuration can be customized via environment variables:
export AWS_REGION="us-east-1" # Default: us-west-2
export CLUSTER_NAME="my-supabase" # Default: supabase-eksAdjust scaling parameters in k8s/values.yaml:
# Horizontal Pod Autoscaler settings
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: 80Modify instance types in infrastructure/eks.py:
# EKS Node Group configuration
instance_types=["t3.medium"] # Change to desired instance type
scaling_config={
"desired_size": 3,
"max_size": 10,
"min_size": 2
}Adjust database settings in infrastructure/rds.py:
# Aurora PostgreSQL configuration
instance_class="db.r6g.large" # Graviton2 instances
backup_retention_period=7 # Backup retention days-
Network Isolation
- All compute resources in private subnets
- Database in dedicated subnets with no internet access
- NAT Gateways provide controlled internet access
-
Security Groups
- Minimal port exposure (only necessary ports)
- Source-based access control
- Application layer filtering
-
Encryption
- RDS encryption at rest with AWS KMS
- S3 bucket encryption with AES-256
- Secrets Manager automatic encryption
-
AWS Secrets Manager
- Centralized secret storage
- Automatic rotation capabilities
- Fine-grained access control
-
External Secrets Operator
- Kubernetes-native secret synchronization
- IRSA (IAM Roles for Service Accounts) authentication
- Automatic secret refresh
-
Least Privilege Access
- Service-specific IAM roles
- Minimal required permissions
- Regular access review and rotation
-
Horizontal Scaling
- HPA scales pods based on CPU/memory usage
- Cluster Autoscaler adds nodes as needed
- Load balancer distributes traffic evenly
-
Database Scaling
- Aurora read replicas for read scaling
- Vertical scaling through instance class changes
- Connection pooling for efficient connection use
-
Storage Scaling
- S3 provides virtually unlimited storage
- Aurora storage auto-scales up to 128TB
- EBS volumes can be expanded as needed
# Re-configure kubectl
aws eks update-kubeconfig --region us-west-2 --name supabase-eks
# Check IAM permissions
aws sts get-caller-identity# Check pod logs
kubectl logs -n supabase <pod-name>
# Check resource availability
kubectl describe pod -n supabase <pod-name># Check External Secrets Operator logs
kubectl logs -n external-secrets-system deployment/external-secrets
# Check ClusterSecretStore status
kubectl describe clustersecretstore aws-secrets-manager-cluster
# Check IRSA configuration
kubectl describe serviceaccount external-secrets-sa -n supabase
# Verify IAM trust policy (common issue: OIDC URL format)
aws iam get-role --role-name supabase-external-secrets-role --query 'Role.AssumeRolePolicyDocument'
# Test service account token manually
kubectl run test-aws --image=amazon/aws-cli --rm -it --restart=Never \
--serviceaccount=external-secrets-sa -n supabase -- aws sts get-caller-identity# Check ALB status in AWS Console
aws elbv2 describe-load-balancers
# Check ingress configuration
kubectl describe ingress -n supabase# Get all resources in namespace
kubectl get all -n supabase
# Check events for errors
kubectl get events -n supabase --sort-by=.metadata.creationTimestamp
# Check resource usage and HPA
kubectl top pods -n supabase
kubectl top nodes
kubectl get hpa -n supabase
# Check External Secrets status
kubectl get clustersecretstore aws-secrets-manager-cluster
kubectl get externalsecrets -n supabase
kubectl describe externalsecret <secret-name> -n supabase
# Check metrics server
kubectl get deployment metrics-server -n kube-system- EKS Cluster Logs: CloudWatch Logs
/aws/eks/supabase-eks/cluster - Application Logs:
kubectl logs -n supabase <pod-name> - External Secrets Logs:
kubectl logs -n external-secrets-system deployment/external-secrets - Metrics Server Logs:
kubectl logs -n kube-system deployment/metrics-server - Cluster Autoscaler Logs:
kubectl logs -n kube-system deployment/cluster-autoscaler - AWS Load Balancer Controller:
kubectl logs -n kube-system deployment/aws-load-balancer-controller
To completely remove all resources and avoid ongoing charges:
./scripts/teardown.shThis script will:
- Remove Supabase Helm release
- Clean up Kubernetes resources
- Delete Load Balancers and Target Groups
- Empty S3 buckets
- Remove security groups
- Destroy all CDKTF-managed infrastructure
If the automated script fails, manually clean up in this order:
-
Kubernetes Resources
helm uninstall supabase -n supabase kubectl delete namespace supabase external-secrets-system
-
Load Balancers
# Delete ALBs from AWS Console or CLI aws elbv2 describe-load-balancers aws elbv2 delete-load-balancer --load-balancer-arn <arn>
-
Infrastructure
cdktf destroy supabase-aws
After teardown, verify no charges:
- Check AWS Cost Explorer
- Verify no running EC2 instances
- Confirm S3 buckets are empty
- Check for any remaining Load Balancers
- SSL/TLS Certificate: Integrate ACM certificates for HTTPS termination
- Custom Domain: Route53 integration for custom domains
- Monitoring Dashboards: CloudWatch dashboards for HPA and External Secrets metrics
- Backup Automation: Automated backup verification and restore testing
- Multi-Region: Cross-region replication and failover capabilities
- CI/CD Integration: GitOps workflow with ArgoCD for automated deployments
- Cost Optimization: Spot instances, reserved capacity, and auto-scaling policies
- Security Hardening: WAF integration, DDoS protection, and security scanning
- Service Mesh: Istio integration for advanced traffic management and security
- Advanced Observability: Prometheus, Grafana, and distributed tracing with Jaeger
- Disaster Recovery: Automated failover and recovery procedures with RTO/RPO targets
- Compliance: SOC2, HIPAA, PCI-DSS and other compliance frameworks
- β HPA Implementation: All critical services auto-scale based on CPU/memory
- β External Secrets: Full AWS Secrets Manager integration with IRSA
- β Metrics Server: Resource metrics collection for scaling decisions
- β Multi-AZ Resilience: Infrastructure distributed across availability zones
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes with tests
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
For issues and questions:
- Check the troubleshooting section above
- Search existing GitHub issues
- Create a new issue with detailed information
- Include logs and configuration for faster resolution
- Supabase for the amazing open-source platform
- Supabase Community for Kubernetes charts
- CDKTF Team for the excellent IaC framework
- AWS for providing robust cloud infrastructure
Happy Building! π