AWS ECS Deployment: Containerized Application with ECR and Fargate

In this project, we embark on an exciting journey into the world of AWS Cloud, diving deep into various services offered by Amazon Web Services. We start by creating an EC2 instance, configuring AWS ECR, and pushing an image to the registry. Our adventure continues with the setup of an AWS ECS cluster, utilizing AWS Fargate, followed by the creation of a task definition. Finally, we learn how to expose our application and access it using the provided IP address. Each step will be detailed thoroughly, offering insights into the process and the reasons behind each action taken.

Amazon Elastic Container Registry (ECR):

Amazon ECR is a fully managed Docker container registry that allows users to store, manage, and deploy Docker container images. It integrates seamlessly with other AWS services, such as ECS and EKS (Elastic Kubernetes Service), providing a secure and scalable solution for storing and deploying container images.

How AWS ECR Works:

Image Storage: ECR allows users to push, pull, and manage Docker container images securely within AWS.
Integration: It integrates seamlessly with ECS, EKS, and CI/CD pipelines, making it easier to manage and deploy containerized applications.
Security: ECR supports encryption at rest and in transit, as well as AWS IAM for access control, ensuring image security.
Scalability: Scales automatically to accommodate the storage needs of container images.

Amazon Elastic Container Service (ECS):

Amazon ECS is a highly scalable, fast, and secure container management service that supports Docker containers and allows users to easily run and scale containerized applications on AWS.

How AWS ECS Works:

1. ECS helps manage and orchestrate Docker containers by deploying and scaling them across clusters of EC2 instances or AWS Fargate.

2. Users define tasks in ECS task definitions, specifying container image, resources, networking, etc.

3. ECS operates within clusters, which are logical groupings of EC2 instances or Fargate resources.

4. ECS services maintain a specified number of tasks, ensuring high availability and load balancing.

First, we'll create an EC2 instance named "Node-Todo-App". Then, we'll install docker.io and AWS CLI on our instance.

sudo apt install awscli
sudo apt install docker.io -y

Let's go to the GitHub repository and copy the source code url.

Clone the repository from GitHub to the EC2 instance.

Configuring image in AWS ECR

Now, we'll configure the Amazon Elastic Container Registry (ECR). To do this, we'll head to the AWS Management Console, search for "ECR", and create a new repository there.

While creating the new repository, we'll choose the "public" option in the visibility settings. Then, we'll select all the relevant operating systems and versions based on the OS of Fargate we intend to use. Finally, we'll create the repository.

Looks, our public repository has been successfully created.

Pushing the image to ECR

Now, when we select our repository and click on the "View push command," a similar interface will appear. We'll execute these commands to push our repository, just like how we use Docker image commands to push to Docker Hub. The steps and concepts are exactly the same, only the platforms differ.

When we applied the first command, we encountered an error in our terminal related to AWS configuration. This error occurred because we hadn't configured AWS properly. To fix this issue, we utilized our AWS access key ID and secret access key ID. Then we re-applied our previous commands. Let's give it another shot and proceed.

Additionally, we faced another type of issue: "permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock." To resolve this type of issue, we use the following command:

sudo usermod -aG docker $USER
sudo reboot

This command grants the user permission to execute Docker commands without using sudo for every command, which can be more convenient.

Now, let's reapply our commands to see if they're working properly

It seems we've successfully logged in, so now we'll execute the remaining commands to push our repository.

Finally, after applying the push command, we'll check our ECR repository to see if our image has been pushed. It looks like our repository is displaying the image, indicating that the image has been successfully pushed.

Configuring AWS ECS

Now, we'll use this image in the ECS cluster. We'll start by searching 'ECS' in the AWS console and then creating a new cluster.

For the cluster, we'll choose a suitable name and select AWS Fargate as our cluster type. Although we have the option to add a custom VPC and subnet for our application, for now, we'll skip this part. Simply clicking the create button will create our cluster.

Reason why we are Using AWS Fargate:

One of the major disadvantages of using AWS EC2 for an application is we have to create multiple instances in case of an application load increase that will have a cost impact.

To avoid this, we will use AWS Fargate which is a serverless technique of providing the specification of applications that will be automatically managed without spinning off any instance.

We'll check our ECS cluster creation process in the CloudFormation.

It seems our cluster is now ready.

Create a Task Definition for the cluster

Just as we are required to run a container using an image, in the same way, we need to create a task definition for the cluster.

A Task Definition in Amazon ECS is crucial as it specifies how Docker containers run within a cluster. It defines container configurations, including Docker image, CPU, memory, networking, and storage settings. Task Definitions ensure consistent deployments, simplify scaling, and support versioning for updates. They serve as blueprints, maintaining a single source of truth for container configurations and enabling ECS Services to manage desired tasks efficiently.

Go to Task definitions --> Create a new task definition

The task definition name must be unique

Enter the Name, Container Image URI, and Port Mapping (ensuring the exposed port matches the one in the Dockerfile used to create the image, for instance, 8000).

In the Container details section, provide the container's name and its image URL. Additionally, in the port mapping section, input the container's port number, aligning it with the port number specified in our Dockerfile used for image creation.

Select the CPU and memory configurations based on the application load.

Keep the rest of the settings as default, then by clicking the 'create' button, our task will be created and deployed onto the cluster.

Expose Our Applications:

Now, to access our application, we need to follow a few steps. First, clicking on the task ID will open an interface. Then, by clicking on the ENI ID URL, we'll navigate to the network interface summary. After that, we'll access the security group URL, edit the inbound rules, and add port 8000 for our application. Once saved, our task will be completed.

Boooommmmm!!!!!!!!!!!!!

Finally, We'll copy the public IP address and append the port number. After hitting enter, we'll be able to access our application.

Through this project, we've navigated through several essential AWS services, demonstrating the process of deploying applications using AWS ECS and ECR. We learned to configure AWS services, push images to the registry, create clusters, and define tasks. The use of AWS Fargate showcased the advantages of serverless deployment in managing applications efficiently without creating additional instances. Moreover, by configuring security groups, we ensured secure access to our application. This journey was an insightful experience, providing a comprehensive understanding of AWS Cloud services and their functionalities.