Skip to main content

Overview

Load Balancers distribute incoming traffic across your ECS containers. Fjall automatically creates and configures Application Load Balancers (ALB) when you deploy ECS services with ComputeFactory - you don’t need to create them manually.

Automatic Provisioning

When you use ComputeFactory with type: "ecs", Fjall automatically:
  • Creates an Application Load Balancer
  • Configures target groups for your containers
  • Sets up health checks
  • Provisions SSL certificates (when domain configured)
  • Creates security groups for ALB traffic
// Fjall creates ALB automatically
const api = app.addCompute(
  ComputeFactory.build("API", {
    type: "ecs",
    ecsType: "fargate",
    containerPort: 3000,
    // ALB created and configured automatically
  })
);

Domain Configuration

With Custom Domain

const api = app.addCompute(
  ComputeFactory.build("API", {
    type: "ecs",
    ecsType: "fargate",
    parentDomain: "myapp.com",
    domainConfig: {
      domainName: "api.myapp.com",
    },
  })
);
Fjall automatically:
  1. Creates ALB with HTTPS listener
  2. Provisions SSL certificate via ACM
  3. Creates Route53 A record pointing to ALB
  4. Redirects HTTP → HTTPS

Access the URL

// Get ALB DNS name
console.log(api.service.loadBalancer.loadBalancerDnsName);
// myapp-alb-123456789.us-east-1.elb.amazonaws.com

// Or use your custom domain
// https://api.myapp.com

Health Checks

Fjall configures default health checks:
// Default health check
// Path: /
// Port: containerPort
// Interval: 30 seconds
// Healthy threshold: 2 checks
// Unhealthy threshold: 2 checks

Custom Health Check Path

If your app uses a different health endpoint:
const api = app.addCompute(
  ComputeFactory.build("API", {
    type: "ecs",
    containerPort: 3000,
    // Note: Health check path customization
    // requires accessing the target group after creation
  })
);

// Customize health check
api.service.targetGroup.configureHealthCheck({
  path: "/health",
  interval: Duration.seconds(60),
  timeout: Duration.seconds(5),
  healthyThresholdCount: 2,
  unhealthyThresholdCount: 3,
});

Multi-Service Clusters

Deploy multiple services behind one ALB with path-based routing:
const cluster = app.addCompute(
  ComputeFactory.build("Platform", {
    type: "ecs",
    ecsType: "fargate",
    parentDomain: "myapp.com",
    cluster: {
      domainConfig: {
        domainName: "app.myapp.com",
      },
    },
    services: [
      {
        name: "API",
        ecrRepository: apiRepo,
        containerPort: 3000,
        path: "/api/*",
        priority: 1,
      },
      {
        name: "Web",
        ecrRepository: webRepo,
        containerPort: 80,
        path: "/*",
        priority: 2,
      },
    ],
  })
);
This creates:
  • One ALB for all services
  • Path-based routing rules
  • Separate target groups per service
  • Single SSL certificate for the domain

Load Balancer Types

Application Load Balancer (ALB)

Default for ECS services - automatically created by Fjall:
  • HTTP/HTTPS traffic
  • Path and host-based routing
  • WebSocket support
  • SSL termination
  • Layer 7 routing

Network Load Balancer (NLB)

For TCP/UDP traffic (manual creation required):
import { NetworkLoadBalancer } from "aws-cdk-lib/aws-elasticloadbalancingv2";

const nlb = new NetworkLoadBalancer(this, "NLB", {
  vpc,
  internetFacing: true,
});

// Use with ECS service
const listener = nlb.addListener("Listener", {
  port: 80,
});

listener.addTargets("Target", {
  port: 80,
  targets: [api.service],
});

Accessing Load Balancer Details

Get DNS Name

const api = app.addCompute(
  ComputeFactory.build("API", {
    type: "ecs",
  })
);

// Pass DNS to other resources
const dnsName = api.service.loadBalancer.loadBalancerDnsName;

new CfnOutput(this, "ApiUrl", {
  value: `https://${dnsName}`,
});

Get ARN

const albArn = api.service.loadBalancer.loadBalancerArn;

SSL/TLS Configuration

Automatic HTTPS

With domain configuration, Fjall automatically:
  • Requests ACM certificate
  • Validates via DNS
  • Configures HTTPS listener
  • Redirects HTTP to HTTPS
const api = app.addCompute(
  ComputeFactory.build("API", {
    type: "ecs",
    parentDomain: "myapp.com",
    domainConfig: {
      domainName: "api.myapp.com", // HTTPS automatic
    },
  })
);

Custom Certificate

Use an existing certificate:
import { Certificate } from "aws-cdk-lib/aws-certificatemanager";

const cert = Certificate.fromCertificateArn(
  this,
  "Cert",
  "arn:aws:acm:us-east-1:123456789012:certificate/..."
);

// Attach to ALB listener (requires accessing listener after creation)
api.service.listener.addCertificates("Cert", [cert]);

Connection Draining

Graceful shutdown when scaling down:
api.service.targetGroup.setAttribute(
  "deregistration_delay.timeout_seconds",
  "30"
);

Logging

Enable access logs:
import { Bucket } from "aws-cdk-lib/aws-s3";

const logBucket = new Bucket(this, "AlbLogs", {
  bucketName: "myapp-alb-logs",
});

api.service.loadBalancer.logAccessLogs(logBucket, "alb");

Best Practices

  • Let Fjall create ALBs for ECS services
  • Use custom domains for production deployments
  • Configure health check paths to match your application
  • Set appropriate timeouts based on your app’s response time
  • Use path-based routing for multiple services on one ALB
  • Enable access logs for debugging
  • Monitor target health in CloudWatch
  • Use connection draining for graceful shutdowns

Troubleshooting

Service Unhealthy

If containers fail health checks:
  1. Check health endpoint - Does / or /health return 200?
  2. Verify container port - Does containerPort match your app?
  3. Check container logs - Is the app starting successfully?
  4. Review security groups - Can ALB reach containers?
  5. Adjust timeouts - Does your app need more startup time?

502 Bad Gateway

Common causes:
  • Container not listening on containerPort
  • Health check failing
  • Container crashing on startup
  • Security group blocking ALB → container traffic

SSL Certificate Issues

If HTTPS isn’t working:
  • Verify domain DNS is pointing to Route53 hosted zone
  • Check ACM certificate validation status
  • Ensure parentDomain matches Route53 hosted zone
  • Wait for DNS propagation (can take 24-48 hours)

Cost Optimization

ALB Pricing

  • Fixed cost: ~$16-23/month per ALB
  • Variable cost: Per LCU (Load Balancer Capacity Unit)

Reduce Costs

  • Share ALBs using path-based routing (multi-service clusters)
  • Use NLB for simple TCP traffic (cheaper per connection)
  • Delete unused ALBs from stopped environments
  • Monitor LCU usage in CloudWatch

See Also