How to spin up Fargate based ECS service with ALB (aws cli only)

Cloud Service Image

If you are familier with ECS, the choice would have been EC2 hosts for running container environment. I used to deploy a combination ALB + ECS for ECS services, however management and administartion cost for EC2 instances are costly from operation perspective. Here’s the guide how to test Fargate in ECS and run services with ALB integration in aws cli.

This guide shows how to create each component in aws cli as follows. VPC, subnets and security group must be created for ALB, service configuration in advance. In this article, I created 2 public subnets to spin up ALB and the service across availability zones. Also I created 1 security group to allow http 80 port for ALB and the service’s network configuration.

Here is the official tutorial how to create a VPC with public and private subnets for ECS cluster.

  1. Create a ECS cluster, without EC2 instances but Fargate
  2. Register task definition, simple http container service
  3. Create a target group for container tasks
  4. Create a ALB for internet facing web application
  5. Create a listener and associate it with the target group
  6. Create a service with the associated target group
  7. Clean up everything

Create a ECS cluster, without EC2 instances but Fargate

It’s straightforward to create a ECS cluster in aws cli.

You can run aws ecs create-cluster command with a cluster name. In this sample I created a ECS cluster named fargate-cluster.

$ aws ecs create-cluster --cluster-name fargate-cluster

aws ecs list-clusters returns a list of existing clusters. You should be able to see the created cluster’s arn with this command.

$ aws ecs list-clusters

Register task definition, simple http container service

Fargate requires network mode configuration “awsvpc” in a task definition. What does this do? When we use awsvpc, the exposed container ports are mapped to the attached elastic network interface port.

You must specify containerPort that the container listens to and use the port for application use, then you can omit specifying hostPort if you have the network mode either “awsvpc” or “host”.

Here’s the command to register a task with task definition json file and this json file was taken from the official guide, Tutorial: Creating a Cluster with a Fargate Task Using the AWS CLI.

You can run a service with this task witout any load-balancers if you don’t need scalability and cross-az availability at this point.

$ aws ecs register-task-definition --cli-input-json file://"$(pwd)"/task_definition.json

aws ecs list-task-definitions returns a list of existing tasks you added. You should be able to see the created task arn with this command.

$ aws ecs list-task-definitions

Create a target group for container tasks

Why do we create a target group in here? Because this target group must be associated with ALB’s listener (route the http traffic to the target, the target is in this case containers), and also with a service in ECS cluster. The service configuration takes the target group arn and the network configuration for containers.

In this case container port that is listened on the elastic network interface port is http 80, so we can create a target group with create-target-group command like this.

You need an arn of created target group for next section.

$ aws elbv2 create-target-group --name fargate-target --protocol HTTP --port 80
 --vpc-id <your vpc id> --target-type ip

When you create a target group for Fargate based containers, you must choose ip for target type attribute, not instance type, because tasks on Fargate will use the awsvpc network mode and will be associated with an elastic network interface, not an Amazon EC2 instance. This is important that the targets will not be instances, but IPs of the elastic network interfaces.

You will not need to register-targets manually but after you’ve created a service, assigned IPs for your container will be taken for load-balancing.

I left health check path, and health check configuration in default but off course you may need to configure those parameters as required for your application.

Create a ALB for internet facing web application

Now it’s time to create an ALB facing the internet. You need to specify the VPC and 2 public subnets where traffic goes across availability zones.

The security group is configured to allow only http traffic with the port number 80 for this app.

I checked the command reference, but it seems not to support the listener configuration in the same command. create-load-balancer

$ aws elbv2 create-load-balancer --name fargate-elb --subnets <your subnet id 1> <your subnet id 2> --security-groups <your sg id 1> --scheme internet-facing

Here’s the command to list all existing load-balancers. “State”: {
“Code”: “active”}
must be seen for the created ALB.

$ aws elbv2 describe-load-balancers

Create a listener and associate it with the target group

Create a listener for the ALB and associate the target group with the listener and ALB. Let’s define a simple rule to route traffic to the target group when http port 80 traffic hits our ALB.

There is no modification and just forward http traffic to our targets that will be our container’s port 80, the containers port 80 will be listened on the elastic network interfaces by Fargate.

You need arns of the target group and ALB from the previous sections. Here’s the command of create-listener.

$ aws elbv2 create-listener --load-balancer-arn <arn loadbalancing> --protocol H
TTP --port 80 --default-actions Type=forward,TargetGroupArn=<arn target-group>

This command generates a listener group on the specified ALB with the configuration. Please recall that targets are IPs not instances in this case.

Here’s the command how to confirm the existing listeners in ALB.

$ aws elbv2 describe-listeners --load-balancer-arn <arn loadbalancer>

Create a service with the associated target group

At last, we can create a service in ECS cluster with ALB integration. You need to pass a lot of options to the command aws ecs create-service. So using json file is recommended. Here’s the sample of the command and json file.

$ aws ecs create-service --cluster fargate-cluster --service-name fargate-service --cli-input-json file://"$(pwd)"/sample-fargate-service.json

targetGroupArn is must to specify if your service’s task definition uses the awsvpc network mode (which is required for the Fargate launch type). You must have choosen ip for the target type and the defined tasks will be associated with elastic network interfaces, not an Amazon EC2 instance.

loadBalancerName parameter is not required if you’re using ALB.

The security group in network configuration should allow traffic to the containers and the port must be the same you have configured as containerPort parameter in a task definition usually.

The subnets must be the same of the subnets ALB covers for traffic load-balancing.

Now your service must be running under the configured ALB. Please confirm the assigned FQDN for ALB and access it via your web browser.

Congrats!! You’re able to access your app running on Fargate ECS on ALB’s public FQDN. The FQDN must look like http://fargate-elb-xxxxxxxxx.ap-northeast-1.elb.amazonaws.com/ if you check in console in default.

Clean up everything

Just a simple step to revert everything in aws cli except deregistering the task definition.

$ aws ecs delete-service --cluster fargate-cluster --service fargate-service --force
$ aws elbv2 delete-listener --listener-arn <arn listener>
$ aws elbv2 delete-load-balancer --load-balancer-arn <arn loadbalancer>
$ aws elbv2 delete-target-group --target-group-arn <arn target-group>
$ aws ecs delete-cluster --cluster fargate-cluster

Leave a Reply

Your email address will not be published. Required fields are marked *