How do I set up AWS Fargate with Load Balancer and CloudFront?
In this guide, we will set up an AWS Fargate service fronted by an Application Load Balancer and a CloudFront distribution. Fargate provides serverless computing for containers, allowing you to focus on the application without worrying about the underlying infrastructure. The Load Balancer will distribute incoming traffic to your containerized tasks, and CloudFront will ensure your application’s content is delivered with low latency and high transfer speeds.
What we will do:
- VPC Setup: Create a Virtual Private Cloud (VPC) to host our Fargate service.
- ECS Cluster: Set up an ECS cluster to run our services.
- Task Definition: Define a Fargate task with its configuration.
- Service: Create an ECS service to manage the running tasks.
- Load Balancer: Provision an Application Load Balancer (ALB) to distribute traffic.
- CloudFront: Set up a CloudFront distribution to deliver content globally.
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: Setting up a network for the resources.
- ECS Cluster and Task Definition: Describe how Fargate tasks are run.
- Load Balancer: Handle incoming web requests.
- CloudFront: Ensure low-latency content delivery.
Summary:
We’ve successfully set up AWS Fargate to run containerized applications, an Application Load Balancer to manage traffic, and CloudFront to distribute content globally. This configuration ensures scalable, high-performance, and low-latency delivery for your application deployments.
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.