Your first project on AWS — ALB

Pratik Pednekar
8 min readMar 27, 2022

--

Chapter 3 — Configure GitHub actions, push a Docker image to ECR, connect to service on ECS and configure ALB

Photo by Jon Flobrant on Unsplash

The series

In the previous article, we created, configured, and started an ECS service but it failed to deploy our task as we did not have a Docker image. In this article let’s start by forking a GitHub repo which is a very simple nodejs service capable of getting and creating lists.

GitHub actions is a continuous integration and continuous deployment platform that allows you to automate build, test and deployment pipeline.

Every commit to our repository, will trigger a build, create the application’s Docker image, push it to ECR and deploy it via ECS service. All this is achieved by configuring an existing workflow “Deploy to Amazon ECS”. This has been configured by me and is available to you in the forked repo.

IAM user for GitHub

For GitHub actions to be able to deploy anything to AWS, it would need the required permissions, how do we provide this? The answer is IAM, we have to create an IAM user and provide its access keys to the GitHub account.

Search and select IAM in AWS, on the left menu, select users and click add users. Set the user name and select programmatic access as we only need this for integrating GitHub actions and not to create an AWS console log-in.

setting user name

Click next to add permissions and select attach existing policies. Next, select these 3 policies, AmazonECS_FullAccess, AmazonS3FullAccess, and AmazonEC2ContainerRegistryPowerUser.

set permissions

Click next, leave the tags empty and click review, check and click create the user.

copy the access and secret key

Don’t forget to copy the access key and secret key, we have to add these keys in GitHub. Now, open the GitHub account, select the forked repo and go to the settings tab.

settings

On the left menu, select secrets, click actions, click add repository secret and create 2 secrets, AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY with their respective values.

the access key and secret key

In the root folder of the repo, you will find a folder named .github/workflows, which contains a configuration file for our build and deploy GitHub action.

For adding a new build and deploy task, you can go to actions and select any existing workflow or create a custom flow, for example, we have selected the “Deploy to Amazon ECS” flow which automatically adds a configuration file in the root .github/workflows folder.

configure build and deploy

Open the dev-ecs.yml file and edit these environment variables. Set AWS_REGION to us-west-2, ECR_REPOSITORY to mfp-dev-ecr-falconbackend, ECS_SERVICE to mfp-dev-ecs-service, ECS_CLUSTER to mfp-dev-ecs-cluster, ECS_TASK_DEFINITION to mfp-dev-ecs-taskdefinition and CONTAINER_NAME to mfp-dev-falconservice and commit.

update dev-ecs.yml file

Before we deploy, there is one last task, go to the taskdef_dev folder in the root and open the aws-task-definition.json file. We have to update this with the JSON data of the task definition we have created on AWS.

Find it here, copy the JSON and replace the content of the repository task definition file.

task definition JSON

Once you push this, a new deployment will be triggered under the actions tab on GitHub.

successful deployment

Once deployed, we can check the ECS service in AWS

1 task running

Congratulations, we have successfully deployed a nodejs service on ECS. At this point, we should be able to call our service from anywhere since it is hosted on a public EC2 machine. You can use the public DNS address of the EC2 and call the API but this will not work as we have allowed only ssh connections to our EC2. If you want to allow this, go ahead, and add another rule in the EC2 security group.

We want to host multiple copies of our service on ECS and have a load balancer that would balance the incoming traffic, so, let’s get started.

Create target group

Before we create a load balancer, we must create a target group, a target group tells the load balancer where to route the traffic.

Search and select target groups, since we want to route traffic to ECS EC2 instances, select the target type as instances. Select default VPC and for the health check path, set /api.

target name
health check endpoint

Click next, do not select any EC2 targets, these will be registered once the ECS service is started, then click create target group.

This load balancer will be connected to ECS and ECS can automatically register more target instances as and when more tasks are deployed.

Security group for ALB

Next, we must create a security group for ALB and configure it to accept inbound traffic on HTTP port 80. Outbound traffic will not be restricted.

Search and select security groups, then click create security group, set the name, default VPC, and inbound rules as shown below.

an inbound rule for ALB

Leave the outbound rules as is and save. We have another task here, i.e. to modify the EC2 security group to allow incoming connections from the ALB on port 80. Go to security groups, select EC2 security group, and select edit inbound rules.

EC2 security group

Add new rule as below. For source, select the security group of ALB. This means that only ALB can connect to our EC2 on port 80. Click save.

allow inbound from ALB security group

Create ALB

Now that we have the target group, let’s attach it to the load balancer. In the AWS console, search and select load balancer. Click create load balancer, select application load balancer.

Network load balancer works at the transport layer and just forwards requests whereas application load balancer can examine the HTTP request header and decide where to route the request.

Set scheme as internet-facing since our clients will call our service via the internet.

set name and scheme

Under network mappings, select the default VPC and you need to select at least one availability zone and one subnet for each zone. We have selected us-west-2a and us-west-2b. Subnet selected must be public.

security group for alb

Under the security group, select the one that we just created, then select the target group.

In this project, all our communications will be HTTP only. For HTTPS you will need to setup and configure certificates using ACM (AWS certificate manager).

select target group as mfp-alb-target on port 80

Click create load balancer. Now, that the load balancer is created, we will attach it to our ECS service, so that any new instances are automatically attached to our target group, but AWS does not allow you to attach a load balancer once service is created hence we will need to delete and re-create this service.

delete ecs service

Service creation is described in the previous article, I will just attach the screenshots here. Set the fields as shown below and leave the rest as is.

ECS service creation

Click the next step for load balancing, select ALB and set the default IAM role in the drop down to enable the service to register new targets.

After selecting the ALB, our default container will get loaded, click add to load balancer, and select the target group from the dropdown.

add container
after target group selection

Click next twice and create service. If you go back and check the target group, a new target i.e. our EC2 instance from the ECS cluster will be registered.

Test

Let’s try calling the health check endpoint through the load balancer. To do this, select the load balancer that you created and check its DNS name.

ALB DNS

Open the browser and browse http://your-dns-name/api, this will return you 200 OK which means our service is online and working as expected.

We can now test the two api’s in the service, get and post list. Use postman and check them out as shown below.

create a list
Gets the created lists

In the next chapter, we will add a front end to call our api’s.

If you liked my work, buy me a coffee.

--

--