How Do I Set Up AWS Fargate With Load Balancer and CloudFront?
Introduction
This guide provides a comprehensive walkthrough for setting up an AWS Fargate service, which is fronted by an Application Load Balancer and a CloudFront distribution. AWS Fargate offers serverless computing for containers, enabling you to focus on application development without managing the underlying infrastructure. The Application Load Balancer efficiently distributes incoming traffic to your containerized tasks, while CloudFront ensures that your application’s content is delivered globally with minimal latency and high transfer speeds.
Step-by-Step Setup Process
VPC Setup:
- Create a Virtual Private Cloud (VPC) to host the Fargate service. This VPC will serve as the network environment for your service.
ECS Cluster:
- Set up an ECS cluster where your services will run. This cluster is a logical grouping of tasks or services.
Task Definition:
- Define a Fargate task with its configuration. This includes specifying the container image, resource requirements, and network mode.
Service:
- Create an ECS service to manage the running tasks. The service will ensure the desired number of tasks are running and manage task placement.
Load Balancer:
- Provision an Application Load Balancer (ALB) to distribute incoming traffic evenly across the tasks.
CloudFront:
- Set up a CloudFront distribution to deliver your application’s content globally, enhancing access speed and reliability.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
// Create a VPC
const main = new aws.ec2.Vpc("main", {cidrBlock: "10.0.0.0/16"});
// Create Subnets
const subnetA = new aws.ec2.Subnet("subnet_a", {
vpcId: main.id,
cidrBlock: "10.0.1.0/24",
availabilityZone: "us-west-2a",
});
const subnetB = new aws.ec2.Subnet("subnet_b", {
vpcId: main.id,
cidrBlock: "10.0.2.0/24",
availabilityZone: "us-west-2b",
});
// Create an ECS Cluster
const mainCluster = new aws.ecs.Cluster("main", {name: "example-cluster"});
// Define the task definition
const mainTaskDefinition = new aws.ecs.TaskDefinition("main", {
family: "example-task",
networkMode: "awsvpc",
requiresCompatibilities: ["FARGATE"],
cpu: "256",
memory: "512",
containerDefinitions: JSON.stringify([{
name: "example-app",
image: "nginx",
cpu: 256,
memory: 512,
essential: true,
portMappings: [{
containerPort: 80,
hostPort: 80,
}],
}]),
});
// Create Target Group
const mainTargetGroup = new aws.lb.TargetGroup("main", {
name: "example-tg",
port: 80,
protocol: "HTTP",
vpcId: main.id,
targetType: "ip",
});
// Create Security Group for ECS Tasks
const mainSecurityGroup = new aws.ec2.SecurityGroup("main", {
vpcId: main.id,
ingress: [{
fromPort: 80,
toPort: 80,
protocol: "tcp",
cidrBlocks: ["0.0.0.0/0"],
}],
egress: [{
fromPort: 0,
toPort: 0,
protocol: "-1",
cidrBlocks: ["0.0.0.0/0"],
}],
});
// Create ECS Service
const mainService = new aws.ecs.Service("main", {
name: "example-service",
cluster: mainCluster.id,
taskDefinition: mainTaskDefinition.arn,
desiredCount: 1,
launchType: "FARGATE",
networkConfiguration: {
subnets: [
subnetA.id,
subnetB.id,
],
securityGroups: [mainSecurityGroup.id],
},
loadBalancers: [{
targetGroupArn: mainTargetGroup.arn,
containerName: "example-app",
containerPort: 80,
}],
});
// Security Group for Load Balancer
const lb = new aws.ec2.SecurityGroup("lb", {
vpcId: main.id,
ingress: [{
fromPort: 0,
toPort: 65535,
protocol: "tcp",
cidrBlocks: ["0.0.0.0/0"],
}],
egress: [{
fromPort: 0,
toPort: 0,
protocol: "-1",
cidrBlocks: ["0.0.0.0/0"],
}],
});
// Load Balancer
const mainLoadBalancer = new aws.lb.LoadBalancer("main", {
name: "example-lb",
internal: false,
loadBalancerType: "application",
securityGroups: [lb.id],
subnets: [
subnetA.id,
subnetB.id,
],
});
// Create Listener
const mainListener = new aws.lb.Listener("main", {
loadBalancerArn: mainLoadBalancer.arn,
port: 80,
protocol: "HTTP",
defaultActions: [{
type: "forward",
targetGroupArn: mainTargetGroup.arn,
}],
});
// CloudFront Distribution
const mainDistribution = new aws.cloudfront.Distribution("main", {
origins: [{
domainName: mainLoadBalancer.dnsName,
originId: "exampleALB",
}],
defaultCacheBehavior: {
allowedMethods: [
"GET",
"HEAD",
],
cachedMethods: [
"GET",
"HEAD",
],
targetOriginId: "exampleALB",
forwardedValues: {
queryString: false,
cookies: {
forward: "none",
},
},
viewerProtocolPolicy: "redirect-to-https",
},
enabled: true,
isIpv6Enabled: true,
comment: "Example CloudFront Distribution",
defaultRootObject: "index.html",
restrictions: {
geoRestriction: {
restrictionType: "none",
},
},
viewerCertificate: {
cloudfrontDefaultCertificate: true,
},
});
export const albDnsName = mainLoadBalancer.dnsName;
export const cloudfrontDistributionId = mainDistribution.id;
Key Points
- VPC and Subnets: Establish a network environment for the resources.
- ECS Cluster and Task Definition: Configure how Fargate tasks are executed.
- Load Balancer: Manage and distribute incoming web traffic.
- CloudFront: Ensure efficient and low-latency content delivery.
Conclusion
In this guide, you have successfully set up AWS Fargate to run containerized applications, configured an Application Load Balancer to manage traffic, and implemented CloudFront to distribute content globally. This setup provides a scalable, high-performance, and low-latency solution for deploying your applications, ensuring optimal performance and user experience.
Deploy this code
Want to deploy this code? Sign up for a free Pulumi account to deploy in a few clicks.
Sign upNew to Pulumi?
Want to deploy this code? Sign up with Pulumi to deploy in a few clicks.
Sign upThank you for your feedback!
If you have a question about how to use Pulumi, reach out in Community Slack.
Open an issue on GitHub to report a problem or suggest an improvement.