Skip to content

abdelrazekrizk/Deploy-Web-Application-on-Amazon-ECS-Using-Fargate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Developing and Deploying a Basic Web Application on Amazon ECS Using Fargate

Architecture Diagram:

This is a guide on how to Developing and Deploying a Basic Web Application on Amazon ECS

Learning Objectives:

  • Gain hands-on experience with containerization using Docker.
  • Understand how to use Amazon ECR to store and manage container images.
  • Learn the basics of creating and managing an Amazon ECS cluster.
  • Learn about ECS and its role in orchestrating containerized applications, including task definitions, clusters, and services.

Whether you are new to Amazon ECS or looking to level up your skills, this repository has you covered.

Note: that Tutorial using AIM with Administrative User.
Assuming you have an AWS account, Docker Engine AWS CLI follow these steps:

Note: that Tutorial using EC2 with ubuntu-jammy-22.04-amd64-server Operation System
Docker version 24.0.5, build 24.0.5-0ubuntu1~22.04.1
For other Operation System Follow the Official Docker Documunts here.

Below are the steps to follow:

Table of Contents

Step 1: Create a NodeJS Server Web Application.

Create a basic Node.js Server Web Application.
server.js:

Step 2: Create a Dockerfile

Create a Dockerfile to containerize the Flask application.
Dockerfile:

Step 3: Build, Run Docker Image and Test Locally.

  • Open a terminal or command prompt and navigate to the directory containing the Dockerfile and run the following command:
docker build -t <image-name> .
  • Run the newly built image.
docker run -p <container-Port>:<host-Port> <image-name>
  • Replace:
    <image-name> with your image-name ex: hello-world.
    <container-Port> with your container-Port define within Dockerfileex: 3000.
    <host-Port> with the application port to listen on host-Port ex: 3000.

  • Access http://localhost:3000 or http://127.0.0.1:3000/in your web browser to see the "Hello, this is a basic web application running on Amazon ECS!" message

Step 4: Build and Push Docker Image to Amazon ECR Repository.

  • Create an ECR repository to store your Docker images.
  • Make note of the repository URI.

4.1. Ensure ECR Permissions.

  • Verify that your IAM user or role has the necessary permissions to access the ECR repository.
    The required permissions include:

ecr:GetAuthorizationToken
ecr:BatchCheckLayerAvailability

You can attach the AmazonEC2ContainerRegistryPowerUser policy to your IAM user or role to grant these permissions.

4.2. Log in to AWS ECR.

private Registry.

  • Authenticate a private registry.
aws ecr get-login-password --region <your-region> | docker login --username AWS --password-stdin <aws_account_id>.dkr.ecr.<your-region>.amazonaws.com
  • Replace:
    <your-region> with your desired region.
    <aws_account_id> with your aws_account_id

4.3. Create a Private Amazon ECR Repository.

aws ecr create-repository \
        --repository-name <repository-name> \
        --region <your-region>
  • Replace:
    <repository-name> with your repository-name.
    <your-region> with your desired region.

4.4. Tag and Push Docker Image.

  • Tag the image to push to your private repository.
  • List the images you have stored locally to identify the image to tag and push.
docker images
  • Tag the image to push to Amazon ECR private repository.
docker tag <image-name:tag> <aws_account_id>.dkr.ecr.<your-region>.amazonaws.com/<repository-name:tag>
  • Push the image.
docker push <aws_account_id>.dkr.ecr.<your-region>.amazonaws.com/<repository-name:tag>
  • Replace:
    <image-name:tag> with your image-name:tag ex: hello-world:latest
    <aws_account_id> with your aws_account_id.
    <your-region> with your desired region.
    <repository-name> with your repository-name.
    Note: ECR repository URI= <aws_account_id>.dkr.ecr.<your-region>.amazonaws.com/<repository-name:tag>

Follow the Official Documunts Amazon Quick start: Publishing to Amazon ECR Pprivate repository using the AWS CLI here.

Public Registry.

  • Authenticate a public registry.
aws ecr-public get-login-password --region <your-region> | docker login --username AWS --password-stdin public.ecr.aws

4.5. Create a Public Amazon ECR Repository.

  • Open a terminal or command prompt and navigate to the ECR directory and run the following command:.
aws ecr-public create-repository \
        --repository-name <repository-name> \
        --catalog-data file://repositorycatalogdata.json \
        --region <your-region>
  • Replace:
    <repository-name> with your repository-name.
    <your-region> with your desired region.

4.6. Tag and Push Docker Image.

  • Tag and Push an image to Amazon ECR Publicrepository.
    List the images you have stored locally to identify the image to tag and push.
docker images
  • Tag the image to push to your repository with your public repository URI
    which was in the response to the create-repository call you made in the previous step.
docker tag <image-name:tag> public.ecr.aws/<registry_alias>/<repository-name>
  • Push the image to the Amazon ECR.
docker push public.ecr.aws/<registry_alias>/<repository-name>
  • Pull the image from the Amazon ECR.
docker pull public.ecr.aws/g7p1j8g3/hello-flask:v.1
  • Replace:
    <registry_alias> with your registry_alias.
    <repository-name> with your repository-name.

Follow the Official Amazon Quick start: Publishing to Amazon ECR Public using the AWS CLI here.

Step 5: Create an Amazon VPC.

  • you can create VPC using AWS CLIor cloudformation
  • Create an Amazon VPC in two availability zone with two Public and two Private subnets and configure security group rules to allow traffic on Port 3000using AWS CLI.

5.1. Create VPC:

  • Open a terminal or command prompt and run the following command:.
aws ec2 create-vpc \
    --cidr-block <CIDR block> \
    --region <your-region> \
    --tag-specification ResourceType=vpc,Tags='<Tags>'
  • Replace:
    <CIDR block> with your desired CIDR block.ex: 10.0.0.0/16.
    <your-region> with your desired region.
    <Tags> with your desired Tags ex: Tags='[{Key=Name,Value="ECS-VPC"},{Key=Owner,Value="Network Team"}]'.
  • Retrieve the VPC ID:
aws ec2 describe-vpcs \
        --query 'Vpcs[0].VpcId'
  • outputs
"vpc-0fc3b7820d89cea5a"
  • Make note and write down VpcId:

5.2. Create Internet Gateway:

  • allows communication between your VPC and the internet.
aws ec2 create-internet-gateway \
        --region <your-region> \
        --tag-specification ResourceType=internet-gateway,Tags='<Tags>'

5.3. Attach Internet Gateway to VPC:

  • Retrieve the Internet Gateway ID:
aws ec2 describe-internet-gateways \
        --query 'InternetGateways[0].InternetGatewayId'
  • outputs
"igw-024ee93e80e7ca1ec"
  • Make note and write down InternetGatewayId:
aws ec2 attach-internet-gateway \
        --internet-gateway-id <Internet-Gateway-ID> \
        --vpc-id <VPC_ID>
  • Replace:
    <VPC_ID> with your Retrieved VPC ID .
    <Internet-Gateway-ID> with your Retrieved INTERNET GATEWAY ID .
    <your-region> with your desired region.
    <Tags> with your desired Tags ex: Tags='[{Key=Name,Value="ECS Internet-Gateway"},{Key=Owner,Value="Network Team"}]'.

5.4. Create Subnets:

  • Create two Subnets on one availability zone .
aws ec2 create-subnet \
        --vpc-id <VPC_ID> \
        --cidr-block <CIDR block> \
        --region <your-region> \
        --availability-zone <your-az-1> \
        --tag-specification ResourceType=subnet,Tags='<Tags>'
  • Create two Subnets on second availability zone .
aws ec2 create-subnet \
        --vpc-id <VPC_ID> \
        --cidr-block <CIDR block> \
        --region <your-region> \
        --availability-zone <your-az-2> \
        --tag-specification ResourceType=subnet,Tags='<Tags>'
  • Replace:
    <VPC_ID> with your Retrieved VPC ID .
    <CIDR block> with your desired CIDR block. ex: 10.0.1.0/24.
    <your-region> with your desired region.
    <your-az-1>,<your-az-2> with your desired **availability zones** ex: us-east-1c.<br> with your desired **Tags**ex: Tags='[{Key=Name,Value="ECS private subnets_1"},{Key=Owner,Value="Network Team"}]'`.

Make note and write down:
- Subnets IDs in the VPC <PrivateSubnet01>, <PrivateSubnet02>, <PublicSubnet01>, <PublicSubnet02>.

5.5. Create an Elastic IP (EIP):

  • Allocates two Elastic IP address
aws ec2 allocate-address \
        --domain vpc <VPC_ID> \
        --region <your-region> \
        --tag-specification ResourceType=elastic-ip,Tags='<Tags>'
  • Replace:
    <VPC_ID> with your Retrieved VPC ID .
    <your-region> with your desired region.
    <Tags> with your desired Tags ex: Tags='[{Key=Name,Value="ECS-elastic-ip"},{Key=Owner,Value="Network Team"}]'.

5.6. Create a NAT Gateway:

  • Creates two NAT gateway for each Public Subnet
aws ec2 create-nat-gateway \
        --subnet-id <subnet-id> \
        --allocation-id <Elastic IP-id> \
        --region <your-region> \
        --tag-specification ResourceType=natgateway,Tags='<Tags>'
  • Replace:
    <subnet-id> with your Retrieved public subnet-id .
    <Elastic IP-id> with your Retrieved region.
    <your-region> with your desired region.
    <Tags> with your desired Tags ex: Tags='[{Key=Name,Value="ECS-NAT-Gateway"},{Key=Owner,Value="Network Team"}]'.

5.7. Create Route Table:

  • Creates four Route Table for your VPC
aws ec2 create-route-table \
        --vpc-id <VPC-ID> \
        --region <your-region> \
        --tag-specification ResourceType=route-table,Tags='<Tags>'
  • Replace:
    <VPC-ID> with your Retrieved .
    <your-region> with your desired region.
    <Tags> with your desired Tags ex: Tags='[{Key=Name,Value="ECS-pub-sub-1-route-table"},{Key=Owner,Value="Network Team"}]'.

5.8. Associates a Route Table with Subnets:

  • Associates each public subnet in your VPC to your public route table
  • Associates each private subnet in your VPC to your each private route table
aws ec2 associate-route-table \
        --route-table-id <route-table-id> \
        --subnet-id <subnet-id>
  • Replace:
    <subnet-id> with your Retrieved subnet-id .
    <route-table-id> with your Retrieved Route Table ID.

5.9. Add Routes to the Route Table :

  • Creates a route betwen private route table and NAT gateway
aws ec2 create-route \
        --route-table-id <route-table-id> \
        --destination-cidr-block 0.0.0.0/0 \
        --gateway-id <Internet-Gateway-ID>
  • Replace:
    <route-table-id> with your Retrieved Route Table ID.
    <gateway-id> with your Retrieved NAT Gateway ID.

5.10. Create Security Group:

aws ec2 create-security-group \
        --group-name <security-group-name> \
        --description <Description> \
        --vpc-id <VPC_ID> \
        --region <your-region> \
        --tag-specification ResourceType=security-group,Tags='<Tags>'
  • Replace:
    <security-group-name> with your desired security-group-name .
    <Description> with your security group description ex: "Security group for port 3000" .
    <VPC_ID> with your Retrieved VPC ID .
    <your-region> with your desired region.
    <Tags> with your desired Tags ex: Tags='[{Key=Name,Value="ECS-security-group"},{Key=Owner,Value="security Team"}]'.

5.11. Configure Security Group Ingress Rules:

aws ec2 authorize-security-group-ingress \
        --group-id <security-group-id> \
        --protocol <protocol> \
        --port <port> \
        --cidr <cidr> \
        --region <your-region> \
        --tag-specification ResourceType=security-group-rule,Tags='<Tags>'
  • Replace:
    <security-group-id> with your Retrieved security group ID .
    <protocol> with your desired protocol ex: protocol name (tcp , udp , icmp , icmpv6 ) or number Protocol_Numbers.
    <port> with port for the application to listen on. ex: 3000 .
    <cidr> with your desired IPv4 CIDR range ex: 0.0.0.0/0 .
    <your-region> with your desired region.
    <Tags> with your desired Tags ex: Tags='[{Key=Name,Value="ECS-security-group"},{Key=Owner,Value="security Team"}]'.

5.12. Create an Amazon VPC using cloud formation.

  • Create an Amazon VPC in two availability zone with two Public and two Private subnets for Amazon ECS .

  • Open a terminal or command prompt and navigate to the cloudformation directory and run the following command:.

      aws cloudformation create-stack \
          --region <your-region> \
          --stack-name <stack-name> \
          --template-body file://amazon-ECS-vpc-private-subnets.yaml
    
  • Replace:
    <your-region> with your region.
    <stack-name> with your stack-name.

  • Navigate to the cloud-formation outputs Make note and write down:
    - Subnets IDs in the VPC <PrivateSubnet01>, <PrivateSubnet02>, <PublicSubnet01>, <PublicSubnet02>
    - SecurityGroups <Security group> -

Step 6: Set Up Amazon ECS.

6.1.Create an ECS Cluster:

aws ecs create-cluster \
        --cluster-name <cluster-name> \
        --region <your-region> \
        --tags <tag>
  • Replace:
    <cluster-name> with your cluster name.
    <your-region> with your desired region.
    <tag> your tag : Add tags for better organization ex: Replace <tag> with Key=name,Value=ECS-project key=dep,value=dev.
    Follow the Official Creating a cluster with a Fargate Linux task using the AWS CLI here

Step 7: Create a Task Definition:

aws ecs register-task-definition \
        --family <task-name> \
        --execution-role-arn "arn:aws:iam::<aws_account_id>:role/ecsTaskExecutionRole" \
        --network-mode <network-mode> \
        --region <your-region> \
        --cpu "<cpu>" \
        --memory "<memory>" \
        --container-definitions '[{"name":"<container-name>","image":"<aws_account_id>.dkr.ecr.<your-region>.amazonaws.com/<image-name>:<tag>","essential":true,"portMappings":[{"containerPort":<container-Port>,"protocol":"tcp"}]}]' \
        --tags <tag>
  • Replace:
    <task-name> with your task-name .
    <aws_account_id> with your aws_account_id.
    <your-region> with your desired region.
    <network-mode> with your desired network-modeThe valid values are none , bridge , awsvpc , and host . If no network mode is specified, the default is bridge .
    <cpu> with your desired cpu ex: "256".
    <memory> with your desired memory ex: "512".
    <container-Port> with your the application port to listen on ex: 3000.
    <image-name>:<tag> with your image-name:tag ex: hello-world:latest.
    <container-name> with the container-name .

Note: ECR repository URI= <aws_account_id>.dkr.ecr.<your-region>.amazonaws.com/<image-name:tag>.

Follow the Official Amazon ECR image and task definition here and here

Step 8: Deploy the Application

8.1.Create an ECS Service launch Type FARGATE:

aws ecs create-service \
        --cluster <cluster-name> \
        --service-name <service-name> \
        --task-definition <task-name> \
        --desired-count 1 \
        --launch-type <launch-type> \
        --region <your-region> \
        --network-configuration "awsvpcConfiguration={subnets=[<PublicSubnet01>,<PublicSubnet02>,<PrivateSubnet01>,<PrivateSubnet02>],securityGroups=[<Security-GroupIds>],assignPublicIp=ENABLED}" \
        --tags <tag>
  • Replace:
    <cluster-name> with your cluster name.
    <service-name> with your service name.
    <task-name> with your task-name .
    <desired-count> with your desired instantiations-number of the specified task definition to place and keep running in your service.
    <your-region> with your desired region.
    <launch-type> with your desired launch-type that match network-mode The Possible values are :EC2, FARGATE and EXTERNAL.
    <subnets-id> with your subnets <security-Group> with your security Groups <tag> your tag : Add tags for better organization ex: Replace <tag> with Key=name,Value=ECS-project key=dep,value=dev.

Step 9: Test the Application.

  1. Open the AWS console here
  2. In the navigation pane, choose Clusters Amazon Elastic Container Service.
  3. Choose the cluster where you ran the service.Cluster overview
  4. In the Cluster overview Choose Services tab, under Service name, choose the service you created in Step 7 Services.
  5. Choose the Tasks tab, and then choose the task in your service.Tasks.
  6. On the task page, in the Configuration section, under Public IP, choose Open address Public IP.
  7. On your browser edit IP and add :3000
  8. Now you can see "Hello, this is a basic web application running on Amazon ECS!"Deployment

Step 10: Cleanup.

  • Cleaning up your resources is an important part of managing your cloud environment.
  • By following these steps, you can ensure that your resources are always clean and tidy and it will also help you to avoid unnecessary costs.

10.1. Deregister Task Definitions:

aws ecs deregister-task-definition \
        --task-definition <task-name>
  • Replace:
    <task-name> with your task-name .

10.2. Delete Task Definitions:

aws ecs delete-task-definitions \
        --task-definition <task-name>
  • Replace:
    <task-name> with your task-name .

10.3. Delete Service:

 aws ecs delete-service \
        --cluster <cluster-name> \
        --service <service-name> \
        --force
  • Replace:
    <cluster-name> with your cluster name.
    <service-name> with your service name.
    <task-name> with your task-name .

10.4. Delete Cluster:

aws ecs delete-cluster \
         --cluster <cluster-name>
  • Replace:
    <cluster-name> with your cluster name.

10.5. CloudFormation Stack:

aws cloudformation delete-stack \
  --stack-name <stack-name>
  • Replace:
    <stack-name> with your stack-name.

10.6. EC2 (Stop or Terminate):

  • To stop an EC2 instance:
aws ec2 stop-instances \
--instance-ids <instance-id>
  • To terminate an EC2 instance:
aws ec2 terminate-instances \
--instance-ids <instance-id>
  • Replace:
    <instance-id> with your instance-ids.

  • Remember to always follow the best practices and guidelines provided by your cloud provider to ensure a smooth and efficient cleanup process.

  • Regularly reviewing and optimizing your resource utilization can not only save costs but also improve the overall performance and efficiency of your cloud infrastructure.

    Keep in mind that this example is minimal and focuses on the basic steps.
    In a production scenario, you would likely include more features, security measures, and configurations.

About

Deploy Web Application on Amazon ECS Using Fargate

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published