Overview
The ECS Cluster resource provides a managed container orchestration platform for deploying and scaling Docker containers on AWS. Fjall offers three deployment options through the ComputeFactory pattern: Fargate (serverless), EC2 Free Tier (development), and EC2 Spot (cost-optimized). Fjall’s ECS implementation is ideal for:- Microservices architectures - Deploy multiple independent services with isolated scaling
- Containerized web applications - Run web apps with automatic load balancing and SSL
- API services - Build scalable REST or GraphQL APIs with health checking
- Background job processing - Execute long-running tasks with automatic recovery
- Three deployment modes - Fargate (serverless), EC2 Spot (cost-optimized), EC2 Free Tier (development)
- Container Insights V2 - Enhanced monitoring with CloudWatch integration
- Factory pattern - Unified interface across all compute types
- Secrets management - Integrated AWS Secrets Manager with KMS encryption
- Circuit breaker deployment - Automatic rollback on failed deployments
- ECS Exec support - SSH-like access to running containers for debugging
Resource Class
ComputeFactory is the ONLY exported class for creating ECS clusters. Direct imports of FargateCluster, EcsFreeTier, or EcsSpot classes are NOT available from the main package exports.
Basic Usage
Fargate Cluster (Default)
With Custom Domain and HTTPS
ComputeFactory Configuration
TheComputeFactory.build() method accepts an IComputeProps object with the following properties:
Core Properties
| Property | Type | Description | Default |
|---|---|---|---|
type | "ecs" | "ec2" | "lambda" | Compute platform type | "ecs" |
ecsType | "fargate" | "freetier" | "spot" | ECS deployment mode (only when type is “ecs”) | "fargate" |
vpc | IVpc | Virtual Private Cloud for cluster | App default VPC |
ecrRepository | Repository | RepositoryImage | ECR repository containing container image | App default registry |
Container Configuration
| Property | Type | Description | Default |
|---|---|---|---|
containerPort | number | Port the container listens on | 80 |
containerEnvironment | {[key: string]: string} | Environment variables for container | {} |
containerSecretsImport | {[key: string]: SecretImport} | Import secrets from other resources/stacks | {} |
dockerfilePath | string | Path to Dockerfile (CLI metadata only, not used in CDK) | None |
Domain and SSL Configuration
| Property | Type | Description | Default |
|---|---|---|---|
domainConfig | DomainConfig | Custom domain with HTTPS | None |
domainConfig is provided:
- Protocol is automatically set to HTTPS
- Certificate is auto-created with DNS validation
- Route 53 A record is automatically configured
Integration Properties
| Property | Type | Description | Default |
|---|---|---|---|
connections | IConnectable[] | Resources to allow network connections to | [] |
Deployment Modes
Fargate (Serverless)
Fargate provides serverless container compute with automatic infrastructure management:- Task count: Fixed at 2 tasks (hardcoded in line 340 of ecs.ts)
- CPU: 256 units (default) - configurable via FargateClusterProps when using direct instantiation
- Memory: 512 MiB (default) - configurable via FargateClusterProps when using direct instantiation
- Capacity provider: FARGATE
- Deployment: Blue/green with circuit breaker
- Container Insights: V2 enabled
- ECS Exec: Enabled for debugging
- The
desiredCountproperty exists in the interface but is IGNORED - the value is hardcoded to 2 in theaddFargateServicemethod - Auto-scaling policy method exists (
addScalingPolicy) but is NEVER CALLED in the constructor - auto-scaling is NOT automatically configured - To enable auto-scaling, you must manually call the
addScalingPolicymethod after instantiation
Free Tier (Development)
Optimized for AWS Free Tier eligibility using a single t3.micro instance:- Instance type: t3.micro (eligible for 750 hours/month free tier)
- Architecture: x86 (standard)
- Min/Max capacity: 1/1 (single instance only)
- Desired count: 1 task
- Memory: 400 MiB (line 289)
- CPU: Not explicitly set at task level
- Entry point:
["node", "main.js"](hardcoded, line 294) - Container Insights: V2 enabled
- ECS Exec: Enabled
Spot Instances (Cost-Optimized)
Uses EC2 Spot Instances with ARM architecture for up to 70% cost savings:- Instance type: m8g.large (ARM64 Graviton processor, line 188)
- Architecture: ARM (AmiHardwareType.ARM, line 191)
- Min/Max capacity: 2/3 instances (lines 186-187)
- Desired count: 3 tasks (line 330)
- Memory: 1024 MiB (line 298)
- CPU: 1 unit (line 297)
- Entry point:
["node", "main.js"](hardcoded, line 303) - Capacity rebalancing: Enabled (automatic replacement before interruption)
- Monitoring: Basic CloudWatch monitoring
- Container Insights: V2 enabled
Factory Pattern Architecture
TheComputeFactory provides a unified interface across all compute types:
- Selects the appropriate ECS implementation based on
ecsType - Injects default VPC and ECR repository from the app context
- Configures protocol (HTTP/HTTPS) based on
domainConfigpresence - Creates security group connections for network management
Network Architecture
Security Group Management
All ECS deployments implement theIConnectable interface:
Database Connectivity
Database connections can be configured through theconnections property or via the IConnectable interface:
databaseConnection property exists in the underlying FargateClusterProps interface but is NOT exposed through ComputeFactory. Use the connections array or manual connection management instead.
Container Configuration
Environment Variables
Pass configuration to your container application:Secrets Management
Import secrets from AWS Secrets Manager using thecontainerSecretsImport property:
- Retrieved from AWS Secrets Manager at runtime
- Decrypted using KMS
- Injected as environment variables in the container
- Kept secure (never logged or exposed)
Container Entry Point
For Free Tier and Spot deployments, the container entry point is hardcoded to["node", "main.js"]. Fargate deployments use the default entry point from the Docker image.
If you need a custom entry point, you must use the underlying class directly (not through ComputeFactory) and pass the containerCommand property.
Default Configuration
All ECS deployments include these defaults:Fargate Defaults
- Container Insights: V2 enabled for enhanced monitoring
- Log retention: 14 days in CloudWatch Logs with prefix
/ecs/{clusterName}/{serviceName} - Deployment circuit breaker: Enabled with automatic rollback
- Health percentages: Min 100%, Max 200% during deployments
- Execute command: Enabled for SSH-like container access
- Health check interval: 120 seconds with 10-second timeout
- ECS-managed tags: Propagated from service to tasks
- Desired count: Fixed at 2 tasks (not configurable via ComputeFactory)
Free Tier Defaults
- Instance: t3.micro (single instance)
- Memory: 400 MiB
- Entry point: [“node”, “main.js”]
- Health check interval: 30 seconds with 15-second timeout
- Desired count: 1 task
Spot Defaults
- Instance: m8g.large ARM (2-3 instances)
- Memory: 1024 MiB
- CPU: 1 unit
- Entry point: [“node”, “main.js”]
- Desired count: 3 tasks
- Health check interval: 30 seconds with 15-second timeout
- Capacity rebalancing: Enabled
Usage Patterns
Pattern 1: Basic Fargate Application
Pattern 2: HTTPS API with Custom Domain
Pattern 3: Container with Environment and Secrets
Pattern 4: Database-Connected Application
Pattern 5: Cost-Optimized with Spot Instances
Pattern 6: Development Environment with Free Tier
Auto-Scaling Configuration
IMPORTANT: Auto-scaling is NOT automatically configured in Fjall ECS clusters. While theaddScalingPolicy method exists in the FargateCluster class, it is NEVER called during construction. If you need auto-scaling, you must:
- Use the underlying
FargateClusterclass directly (not through ComputeFactory) - Manually call the
addScalingPolicymethod after instantiation
- Min capacity: 2 tasks
- Max capacity: 10 tasks
- Target value: 50% utilization
- Scale out cooldown: 60 seconds
- Scale in cooldown: 60 seconds
- Metrics: CPU or Memory utilization
Security Configuration
IAM Roles
All ECS deployments create two IAM roles: Execution Role (used by ECS agent):AmazonECSTaskExecutionRolePolicy(managed)- Secrets Manager read access:
secretsmanager:GetSecretValue,secretsmanager:DescribeSecret - KMS decryption:
kms:Decrypt - SSM Session Manager:
ssmmessages:*for ECS Exec
- Custom inline policies (not available via ComputeFactory)
- AWS managed policies (not available via ComputeFactory)
taskRoleInlinePolicies and taskRoleManagedPolicies properties exist in the underlying FargateClusterProps but are NOT exposed through ComputeFactory. To add custom IAM policies, you must use the underlying class directly.
Security Groups
Cost Optimization
Strategy 1: Use EC2 Spot Instances
EC2 Spot can reduce costs by up to 70% compared to Fargate:- 70% cost reduction vs Fargate
- ARM architecture (Graviton) for additional performance/cost benefits
- Automatic capacity rebalancing handles interruptions
- 2-3 instances with 3 tasks for high availability
Strategy 2: Use Free Tier for Development
- Eligible for 750 hours/month free for first 12 months
- Single t3.micro instance with minimal overhead
- 400 MiB memory optimized for small workloads
Strategy 3: Right-Size Fargate Resources
Fargate charges per vCPU and memory used. Start minimal and scale based on CloudWatch metrics:Advanced Configuration
Custom Health Checks
Health check configuration is set at the load balancer target group level: Fargate Health Checks:- Interval: 120 seconds
- Timeout: 10 seconds
- Path: ”/” (default, not configurable via ComputeFactory)
- Healthy threshold: 2 consecutive successes
- Unhealthy threshold: 2 consecutive failures
- Interval: 30 seconds
- Timeout: 15 seconds
- Path: ”/” (default, not configurable via ComputeFactory)
- Healthy threshold: 3 consecutive successes
- Unhealthy threshold: 3 consecutive failures
healthCheckPath property exists in the underlying props but is NOT exposed through ComputeFactory.
Protocol Configuration
Protocol is automatically determined based on domain configuration:Methods and Properties
Public Properties
connections
Access the security group connections for the ECS service:Connections - CDK Connections object for security group management
Complete Example
Multi-Environment Example
Best Practices
- Use ComputeFactory for all ECS deployments - The factory pattern is the supported API. Direct class imports are not exported.
- Choose the right deployment mode - Fargate for production, Spot for cost-optimization, Free Tier for development.
- Understand task count limitations - Fargate is fixed at 2 tasks. Auto-scaling is not automatically configured.
-
Use Secrets Manager for sensitive data - Never use
containerEnvironmentfor passwords or API keys. Always usecontainerSecretsImport. -
Configure custom domains for production - The
domainConfigproperty automatically enables HTTPS and creates certificates. - Monitor with Container Insights - Automatically enabled by default. Provides deep visibility into container metrics.
- Use the connections property for database access - Automatically configures security group rules.
- Implement proper health checks - Default health check path is ”/”. Ensure your application responds with 200 OK.
- Use ARM architecture for cost savings - Spot instances use m8g.large ARM processors for better price/performance.
- Plan for Spot interruptions - Use Spot instances only for fault-tolerant workloads. Capacity rebalancing is automatic.
Common Patterns
Pattern 1: Microservices Architecture
Deploy multiple services with shared infrastructure:Pattern 2: Multi-Environment Setup
Pattern 3: Scheduled Background Jobs
Use Spot instances for fault-tolerant batch processing:Cost Considerations
| Component | Cost | Optimization |
|---|---|---|
| Fargate tasks | 0.004445/GB/hour | Fixed at 2 tasks with 256 CPU / 512 MB (default). Not configurable via ComputeFactory. |
| Application Load Balancer | 0.008/LCU-hour | One ALB per deployment. Consider path-based routing to share ALBs. |
| NAT Gateway | 0.045/GB processed | Required for private subnet container communication. |
| CloudWatch Logs | 0.03/GB stored | 14-day retention (default). Monitor log volume. |
| EC2 Spot (ecsSpot) | ~70% discount vs Fargate | Uses m8g.large ARM instances. 2-3 instances with 3 tasks. |
| Free Tier (ecsFreeTier) | Eligible for 750 hours/month t3.micro | Single instance. 400 MiB memory. Development only. |
- Dev (Free Tier, 1 t3.micro): ~$0-15/month (free tier eligible)
- Staging (Spot, 2-3 m8g.large): ~$30-50/month
- Production (Fargate, 2 tasks, 256 CPU, 512 MB): ~$30/month
Troubleshooting
Common Issues
-
Cannot import FargateCluster, EcsFreeTier, or EcsSpot classes
- Cause: These classes are not exported from the main package
- Solution: Use
ComputeFactoryfrom@fjall/components-infrastructureinstead. This is the only supported API.
-
Task count is always 2, regardless of desiredCount configuration
- Cause: The
desiredCountvalue is hardcoded to 2 in line 340 of ecs.ts - Solution: This is a known limitation. Fargate deployments always run 2 tasks. Consider using Spot instances (3 tasks) or the underlying class directly if you need different task counts.
- Cause: The
-
Auto-scaling is not working
- Cause: The
addScalingPolicymethod is never called during construction - Solution: Auto-scaling is not automatically configured in Fjall. You must use the underlying
FargateClusterclass directly and manually calladdScalingPolicyafter instantiation.
- Cause: The
-
Protocol is always HTTP, even though I want HTTPS
- Cause: Protocol is determined by the presence of
domainConfig - Solution: Add a
domainConfigobject with your domain name. Protocol will automatically be set to HTTPS (line 272 of compute.ts).
- Cause: Protocol is determined by the presence of
-
Cannot configure health check path
- Cause: The
healthCheckPathproperty is not exposed through ComputeFactory - Solution: This is a limitation of the factory pattern. Use the underlying class directly if you need custom health check paths.
- Cause: The
-
Deployment stuck at “in progress” with no new tasks
- Cause: Insufficient memory/CPU or image pull errors
- Solution: Check CloudWatch Logs for OOM errors or ECR authentication issues. Verify ECR image exists and is accessible.
-
Cannot connect to RDS database from container
- Cause: Security group rules not configured
- Solution: Add the database to the
connectionsarray or manually configure security groups viacluster.connections.allowTo().
-
Free Tier deployment fails with entry point error
- Cause: Container expects different entry point than hardcoded
["node", "main.js"] - Solution: Ensure your Docker image has a
main.jsfile or use the underlying class directly to customize the entry point.
- Cause: Container expects different entry point than hardcoded
-
Spot instance tasks keep restarting
- Cause: Spot instance interruptions or insufficient memory
- Solution: Verify your application can handle interruptions gracefully. Check CloudWatch Logs for memory errors. Spot deployments have 1024 MiB memory allocated.
Debug Commands
Related Resources
- VPC - Network isolation for ECS clusters
- RDS Aurora - Managed PostgreSQL database
- S3 Bucket - Object storage for container data
- Application Load Balancer - HTTP/HTTPS load balancing
- Secrets Manager - Secure credential storage
- ECR Repository - Container image registry
- Lambda Functions - Alternative serverless compute
See Also
- Deploying Containers Guide - Step-by-step container deployment
- Microservices Pattern - Building microservices architecture
- CI/CD Pipeline - Automated container builds and deployments