This Terraform configuration deploys a cost-optimized, production-ready infrastructure for the Bliink application on Google Cloud Platform.
Author: Eshya
- API Backend: Rust application deployed on Cloud Run
- Frontend: React/Expo application deployed on Cloud Run
- Database: PostgreSQL on Cloud SQL with private networking
- Load Balancer: Commented out to save costs ($18/month savings)
- Secrets: Google Secret Manager for environment variables
- Container Registry: Google Artifact Registry
- Networking: VPC with private connectivity for optimal performance
- NAT Gateway: Native GCP NAT Gateway for outbound traffic (replaces proxy VM)
- Region: Singapore (asia-southeast1) for optimal Southeast Asia performance
✅ Cloud Run: Scale to zero when not in use
✅ Database: f1-micro tier with HDD storage (cheapest option)
✅ Database: ZONAL availability (not REGIONAL)
✅ Database: Point-in-time recovery disabled
✅ VPC Connector: 200 Mbps minimum throughput
✅ Load Balancer: Commented out to save $18/month
✅ Secret Manager: Consolidated secrets to minimize costs
✅ Artifact Registry: Cleanup policies enabled
✅ NAT Gateway: Native GCP service for outbound traffic
Estimated Monthly Cost: $80-120 for production environment with NAT Gateway
| Component | Configuration | Estimated Monthly Cost |
|---|---|---|
| Cloud SQL | f1-micro, 10GB HDD, Zonal | $7-10 |
| Cloud Run | Scale to zero, pay per request | $0-5 |
| VPC Connector | 200 Mbps minimum throughput | $9 |
| Cloud Router | NAT Gateway routing | $36 |
| NAT Gateway | Outbound traffic management | $32.4 |
| Static IP | Reused from proxy VM | $7.2 |
| Secret Manager | 1 consolidated secret | $0.06 |
| Artifact Registry | 1GB storage | $0.10 |
| Data Transfer | Low traffic (< 1GB/month) | $1-5 |
| Load Balancer | ||
| Total | $80-120 |
The infrastructure has been migrated from a proxy VM to a native GCP NAT Gateway:
- Native GCP Service: Better reliability and management
- Automatic Scaling: No VM maintenance required
- Better Monitoring: Native GCP logging and metrics
- Simplified Configuration: No proxy setup needed
- Comprehensive Port Access: All common ports included
- Old Proxy VM: $8-15/month (e2-micro + TinyProxy)
- New NAT Gateway: $76.6-80.6/month (Cloud Router + NAT Gateway)
- IP Address: Reused
34.143.143.197from proxy VM - Configuration: Services now use
USE_PROXY=false
- Google Cloud Project: Ensure you have the
api-production-451302project created - Terraform: Install Terraform >= 1.0
- gcloud CLI: Install and authenticate with your GCP account
- Docker: For building and pushing container images
# Authenticate with Google Cloud
gcloud auth login
gcloud config set project api-production-451302
gcloud config set compute/region asia-southeast1
gcloud config set compute/zone asia-southeast1-a-
Navigate to infrastructure directory:
cd infrastructure/ -
Create terraform.tfvars:
cp terraform.tfvars.example terraform.tfvars # Edit terraform.tfvars with your specific values if needed -
Deploy infrastructure only:
terraform init terraform plan terraform apply
-
Or use the deployment script:
./deploy.sh infra # Deploy infrastructure only ./deploy.sh apps # Deploy applications only (after infrastructure) ./deploy.sh all # Deploy both (infrastructure + applications) ./deploy.sh info # Show deployment information
Since this is for studying Terraform, here's the step-by-step manual process:
cd infrastructure/
terraform init
terraform plan -out=tfplan
terraform apply tfplan# Get repository URL from Terraform output
DOCKER_REPO=$(terraform output -raw docker_repository_url)
# Configure Docker authentication
gcloud auth configure-docker asia-southeast1-docker.pkg.dev
# Build and push API (from your separate API repo)
cd /path/to/your/api/repo
docker build -t ${DOCKER_REPO}/api:latest .
docker push ${DOCKER_REPO}/api:latest
# Build and push Frontend (from your separate frontend repo)
cd /path/to/your/frontend/repo
docker build -t ${DOCKER_REPO}/frontend:latest .
docker push ${DOCKER_REPO}/frontend:latest
# Update Cloud Run services
API_SERVICE=$(terraform output -raw api_service_name)
FRONTEND_SERVICE=$(terraform output -raw frontend_service_name)
gcloud run services update ${API_SERVICE} \
--image=${DOCKER_REPO}/api:latest \
--region=asia-southeast1
gcloud run services update ${FRONTEND_SERVICE} \
--image=${DOCKER_REPO}/frontend:latest \
--region=asia-southeast1This setup uses Google Secret Manager for storing sensitive environment variables. This is the most cost-effective and secure option for GCP, costing only ~$0.06/month per secret.
- ✅ Native GCP integration: Works seamlessly with Cloud Run
- ✅ Cost-effective: Much cheaper than Vault or other solutions
- ✅ Easy to manage: Simple CLI and UI interface
- ✅ Secure: IAM-based access control
- ✅ Automatic rotation: Supports secret versioning
Useful Terraform commands for studying:
# Initialize Terraform (download providers)
terraform init
# Check configuration syntax
terraform validate
# Format configuration files
terraform fmt
# Plan changes (dry run)
terraform plan
# Apply changes
terraform apply
# Show current state
terraform show
# List resources in state
terraform state list
# Show specific resource
terraform state show <resource_name>
# Show outputs
terraform output
# Destroy all resources
terraform destroyTo destroy all resources:
terraform destroyWarning: This will permanently delete all data including the database!
Automatically generated diagrams of the infrastructure are available in the diagrams/ folder:
bliink_production_architecture.png: High-level GCP architecture with NAT Gatewaybliink_network_production.png: Detailed network architecturebliink_costs_production.png: Cost breakdown with NAT Gatewaybliink_nat_gateway_architecture.png: NAT Gateway architecture detailsbliink_migration_comparison.png: Migration comparison (Proxy VM → NAT Gateway)bliink_nat_firewall_rules.png: NAT Gateway firewall rules
To regenerate these diagrams, run:
./generate_diagrams.shThe images will be saved in the diagrams/ folder.
- API Backend (Port: 8082): Main Rust API service
- Frontend (Port: 3000): React/Expo frontend
- Auth API (Port: 8080): Authentication service
- Member API (Port: 8081): Member management service
- Company API (Port: 8083): Company management service
- Travel Policy API (Port: 8084): Travel policy service
- CRM API (Port: 8085): CRM backend service
- CRM Frontend (Port: 3001): CRM frontend
- Search API (Port: 8086): Search service with external API integration
- Reservation API (Port: 8087): Reservation management service
- VPC:
cloud-sql-network(10.0.0.0/20) - VPC Connector:
serverless-vpc-connector(10.8.0.0/28) - Cloud Router:
nat-router-production(BGP ASN: 64514) - NAT Gateway:
nat-gateway-production(34.143.143.197) - Firewall Rules: Comprehensive EGRESS rules for external API access
- Cloud SQL: PostgreSQL 15 with private networking
- Redis Cache: Memorystore Redis 1GB Basic Tier
- Cloud Storage: Multi-region ASIA bucket for file storage
- Secret Manager: Environment variables and API keys
- Private Networking: All services use private IP addresses
- IAM: Role-based access control
- SSL/TLS: Encrypted connections for all services





