AWS CDK deployment for the Laminar platform on Amazon ECS Fargate
This directory contains TypeScript-based AWS CDK code to deploy the complete Laminar platform on AWS Fargate, providing a fully managed, serverless container deployment.
New to this deployment? Start here:
- QUICKSTART.md - Get up and running in 30 minutes
- DEPLOYMENT.md - Comprehensive deployment guide
- ARCHITECTURE.md - Architecture details and comparison with Helm
# Install dependencies
npm install
# Generate secure secrets
npm run generate-secrets > secrets.json
# Deploy to AWS
npm run deploy
- Architecture Overview
- Features
- Prerequisites
- Installation
- Configuration
- Deployment
- Post-Deployment
- Monitoring
- Scaling
- Cost Estimation
- Troubleshooting
- Production Considerations
- Documentation
The deployment creates the following AWS resources:
- ECS Cluster on Fargate for container orchestration
- 6 ECS Services:
- Frontend (Next.js app)
- App Server (with nginx sidecar)
- PostgreSQL
- ClickHouse
- Redis (Valkey)
- RabbitMQ
- VPC with public and private subnets across 2 availability zones
- Application Load Balancer (ALB) for frontend (internet-facing)
- Network Load Balancer (NLB) for app server (internet-facing)
- Cloud Map for service discovery (private DNS)
- Security Groups for network isolation between services
- EFS File Systems for persistent storage:
- PostgreSQL data
- ClickHouse data
- RabbitMQ data
- AWS Secrets Manager for storing sensitive credentials and configuration
- IAM Roles with least-privilege access
- Encrypted EFS file systems
- Private subnets for database and internal services
✅ Fully Managed: Serverless container deployment with AWS Fargate
✅ Infrastructure as Code: TypeScript-based CDK for version control and repeatability
✅ High Availability: Multi-AZ deployment with automatic failover
✅ Secure by Default: AWS Secrets Manager, encrypted EFS, VPC isolation
✅ Auto-scaling Ready: Built-in integration with Application Auto Scaling
✅ Monitoring: CloudWatch Logs and metrics for all services
✅ Service Discovery: AWS Cloud Map for internal service communication
✅ Load Balanced: ALB for frontend, NLB for app server
- 6 Containerized Services: Frontend, App Server, PostgreSQL, ClickHouse, Redis, RabbitMQ
- VPC: Public and private subnets across 2 availability zones
- EFS: Persistent storage for PostgreSQL, ClickHouse, and RabbitMQ
- Load Balancers: Application Load Balancer (frontend) and Network Load Balancer (app server)
- Security: Secrets Manager, security groups, encrypted storage
- Observability: CloudWatch Logs with 1-week retention
- AWS Account with appropriate permissions (Administrator recommended for first deployment)
- AWS CLI configured with valid credentials
- Node.js version 18 or later
- npm or yarn package manager
- Sufficient AWS Service Quotas:
- Fargate vCPUs: at least 20
- Elastic IPs: at least 2
- VPC resources: default limits are usually sufficient
- Install dependencies:
npm install
- Bootstrap CDK (if not already done for your account/region):
npx cdk bootstrap aws://ACCOUNT-NUMBER/REGION
Before deploying, you should update the secrets in AWS Secrets Manager or modify the secret values in lib/laminar-stack.ts
:
NEXTAUTH_SECRET
- NextAuth secret keyRABBITMQ_ERLANG_COOKIE
- RabbitMQ Erlang cookieRABBITMQ_DEFAULT_USER
- RabbitMQ admin usernameRABBITMQ_DEFAULT_PASS
- RabbitMQ admin passwordCLICKHOUSE_USER
- ClickHouse usernameCLICKHOUSE_PASSWORD
- ClickHouse passwordPOSTGRES_USER
- PostgreSQL usernamePOSTGRES_PASSWORD
- PostgreSQL passwordPOSTGRES_DB
- PostgreSQL database nameAEAD_SECRET_KEY
- AEAD encryption keySHARED_SECRET_TOKEN
- Shared secret tokenAWS_ACCESS_KEY_ID
- AWS access key for S3AWS_SECRET_ACCESS_KEY
- AWS secret key for S3S3_TRACE_PAYLOADS_BUCKET
- S3 bucket name for trace payloads
You can customize the deployment by setting environment variables or modifying the stack parameters:
CDK_DEFAULT_ACCOUNT
- AWS account ID (auto-detected)CDK_DEFAULT_REGION
- AWS region (default: us-east-1)
Update the NEXTAUTH_URL
in the Frontend service configuration with your actual frontend URL after deployment.
Preview the CloudFormation template:
npm run synth
See what will be deployed:
npm run diff
Deploy the stack:
npm run deploy
Or with CDK CLI:
cdk deploy
The deployment will take approximately 15-20 minutes. After successful deployment, you'll see outputs including:
- Frontend URL (ALB DNS name)
- App Server URL (NLB DNS name)
- Secrets Manager ARN
- ECS Cluster Name
- VPC ID
After deployment, update the secrets in AWS Secrets Manager:
aws secretsmanager update-secret \
--secret-id laminar/app-secrets \
--secret-string file://secrets.json
Update the NEXTAUTH_URL
environment variable in the Frontend ECS task definition with the actual ALB URL.
- Frontend: Use the Frontend URL from the stack outputs
- App Server API: Use the App Server URL from the stack outputs (only
/v1/*
endpoints are accessible)
The deployment uses the following resource allocations:
Service | CPU | Memory | Storage |
---|---|---|---|
Frontend | 2048 (2 vCPU) | 4 GB | - |
App Server | 2048 (2 vCPU) | 8 GB | - |
PostgreSQL | 2048 (2 vCPU) | 4 GB | 20 GB (EFS) |
ClickHouse | 2048 (2 vCPU) | 4 GB | 50 GB (EFS) |
Redis | 256 (0.25 vCPU) | 1 GB | - |
RabbitMQ | 4096 (4 vCPU) | 4 GB | 5 GB (EFS) |
These can be adjusted in lib/laminar-stack.ts
as needed.
Approximate monthly costs (us-east-1):
- Fargate: ~$250-300/month (6 services running continuously)
- Load Balancers: ~$50/month (ALB + NLB)
- EFS: ~$10-20/month (depending on usage)
- CloudWatch Logs: ~$5-10/month
- Secrets Manager: ~$1/month
- Data Transfer: Variable depending on traffic
Total estimated cost: ~$320-380/month for a production deployment
CloudWatch Logs are automatically configured for all services with 1-week retention. You can view logs in the AWS Console:
- Navigate to CloudWatch > Log groups
- Look for log groups prefixed with
/aws/ecs/
To scale services, update the desiredCount
in the service definitions in lib/laminar-stack.ts
:
const frontendService = new ecs.FargateService(this, 'FrontendService', {
// ...
desiredCount: 3, // Scale to 3 instances
});
Then redeploy:
npm run deploy
To delete all resources:
npm run destroy
Or with CDK CLI:
cdk destroy
Note: EFS file systems are set to RETAIN
by default to prevent accidental data loss. You'll need to manually delete them from the AWS Console if you want to remove all resources completely.
Check CloudWatch Logs for each service to see error messages.
Verify security group rules allow traffic between services:
aws ec2 describe-security-groups --group-ids <security-group-id>
Ensure the task execution role has permissions to mount EFS:
aws ecs describe-task-definition --task-definition <task-def-arn>
The CDK deployment has some differences from the Helm chart:
- Service Discovery: Uses AWS Cloud Map instead of Kubernetes DNS
- Persistent Storage: Uses EFS instead of EBS volumes
- Load Balancing: Uses AWS ALB/NLB instead of Kubernetes ingress
- Secrets: Uses AWS Secrets Manager instead of Kubernetes secrets
- Nginx Configuration: Currently embedded as environment variable (consider using EFS or custom image for production)
For production deployments, consider:
- Use a custom domain with Route 53 and ACM for SSL/TLS
- Enable ALB access logs for auditing
- Implement auto-scaling policies for services
- Use RDS for PostgreSQL instead of Fargate task
- Use ElastiCache for Redis instead of Fargate task
- Use Amazon MQ for RabbitMQ instead of Fargate task
- Implement backup strategies for EFS
- Set up CloudWatch alarms for monitoring
- Use parameter store or external secrets for configuration
- Create separate stacks for different environments (dev/staging/prod)
- QUICKSTART.md - Quick start guide (30 minutes to deployment)
- DEPLOYMENT.md - Comprehensive deployment guide with all details
- ARCHITECTURE.md - Architecture details and Helm vs CDK comparison
- config.example.ts - Configuration examples for different environments
cdk/
├── bin/
│ └── laminar.ts # CDK app entry point
├── lib/
│ └── laminar-stack.ts # Main stack definition
├── scripts/
│ └── generate-secrets.ts # Secret generation utility
├── package.json # Dependencies and scripts
├── tsconfig.json # TypeScript configuration
├── cdk.json # CDK configuration
├── README.md # This file
├── QUICKSTART.md # Quick start guide
├── DEPLOYMENT.md # Deployment guide
├── ARCHITECTURE.md # Architecture documentation
└── config.example.ts # Configuration examples
npm run build # Compile TypeScript to JavaScript
npm run watch # Watch for changes and compile
npm run synth # Synthesize CloudFormation template
npm run deploy # Deploy stack to AWS
npm run destroy # Delete stack from AWS
npm run diff # Compare deployed stack with local changes
npm run generate-secrets # Generate secure secrets
The following environment variables can be used to configure the deployment:
CDK_DEFAULT_ACCOUNT
- AWS account ID (auto-detected from AWS CLI)CDK_DEFAULT_REGION
- AWS region (default: us-east-1)AWS_PROFILE
- AWS CLI profile to use
- Rotate Secrets: Use the
generate-secrets
script to create new secrets - Limit Access: Use IAM policies to restrict access to resources
- Enable MFA: Require MFA for sensitive operations
- Use VPN: Access internal services only through VPN or bastion host
- Monitor Logs: Set up CloudWatch alarms for suspicious activity
- Update Images: Regularly update container images for security patches
- Backup Data: Enable EFS backups and test restore procedures
Feature | Helm/Kubernetes | CDK/Fargate |
---|---|---|
Portability | ✅ Multi-cloud | |
Operational Overhead | ❌ High | ✅ Low |
Cold Start | ✅ 5-10s | |
Learning Curve | ❌ Steep | ✅ Moderate |
Cost | ~$290/month | ~$320/month |
Node Management | ❌ Required | ✅ None |
See ARCHITECTURE.md for detailed comparison.
Yes! For production, it's recommended to use Amazon RDS for PostgreSQL. Update the DATABASE_URL
to point to your RDS instance and remove the PostgreSQL service from the stack.
Request an ACM certificate, add an HTTPS listener to the ALB, and attach the certificate. See DEPLOYMENT.md for details.
Yes! You can create separate stacks for dev/staging/prod by instantiating multiple stack instances with different configurations.
- Deploy the CDK stack
- Use
pg_dump
/pg_restore
for PostgreSQL - Export/import data for ClickHouse and RabbitMQ
- Update DNS to point to new load balancers
- Enable EFS backups
- Consider multi-region deployment
- Document restore procedures
- Test backups regularly
To contribute to this CDK code:
- Fork the repository
- Make changes in
lib/laminar-stack.ts
- Test with
npm run synth
- Deploy to a test AWS account
- Submit a pull request with description
- Issues: Create an issue in the repository
- AWS Support: Contact AWS Support for service-specific issues
- Community: Join discussions in the project's community channels
Same as the parent Laminar project.
Built with:
- AWS CDK - Infrastructure as Code
- Amazon ECS - Container orchestration
- AWS Fargate - Serverless compute
- Amazon EFS - Persistent storage
Planned improvements:
- Multi-region support
- RDS integration option
- ElastiCache integration option
- Amazon MQ integration option
- Automated backup configuration
- Custom domain support in CDK
- WAF integration
- Auto-scaling policies
- Cost optimization recommendations
- Monitoring dashboards
Ready to deploy? Start with QUICKSTART.md! 🚀