How to Run a Application on AWS ECS: A Step-by-Step Guide

How to Run a Application on AWS ECS: A Step-by-Step Guide

avatar

Phong Nguyen

2023.12.25

Xây dựng ECS Cluster EC2 launch type, Build custom nginx app bằng docker và chạy trên ECS Cluster.

Lab Details

  1. Bài Lab này sẽ hướng dẫn bạn các bước để khởi chạy và configure custom nginx container trên ECS Cluster.
  2. Duration: 60 minutes
  3. AWS Region: US East (N. Virginia) us-east-1

Architecture Diagram

Images

Task Details

  1. Create VPC
  2. Create EC2 đặt ở Public Subnet (Đóng vai trò như là bastion host)
  3. Create ECR repository and build Docker image
  4. Create ECS Cluster
  5. Create Task definition
  6. Create TG
  7. Create ALB
  8. Create ECS Service
  9. Test hoạt động
  10. Setting Route53 and access website (optional)

1. Create VPC (VPC + IGW + Subnet + Route Table + NAT)

VPC settings

  • Resources to create: VPC and more
  • Auto-generate: check
  • Name: d-vpc-002
  • IPv4 CIDR block: 10.1.0.0/16
  • Number of Availability Zones (AZs) : 2
  • Number of public subnets: 2
  • Number of private subnets: 2
  • NAT gateways ($): In 1 AZ
  • VPC endpoints: S3 Gateway
  • Còn lại để default

Images

2. Create EC2 đặt ở Public Subnet (Đóng vai trò như là bastion host)

Chúng ta cần tạo 1 EC2 cho mục đích build docker image và push lên ECR, việc này có thể thực hiện ở local (Nếu như môi trường local của bạn đã được cài đặt docker)

Bastion host cũng có thể access đến private instance khi cần troubleshooting.

Note: Nếu local đã chạy được docker, có thể bỏ qua step này

2.1 Create Security Group cho Bastion host

  • Name: d-sg-SAA-basion-host
  • Description: Allow ssh from internet
  • VPC: d-vpc-002-vpc
  • Inbound rules
    TypeProtocolPort rangeSource
    SSHTCP220.0.0.0/0
  • Outbound rules
    TypeProtocolPort rangeSource
    All trafficAllAll0.0.0.0/0
  • Tags
    Keyvalue
    Named-sg-SAA-basion-host

2.2 Create EC2

  • Name: d-ec2-SAA-bastion-host
  • OS: Default (Amazon Linux 2023)
  • Instance type: Default (t2.micro)
  • Key pair: d-key-SAA-common (Nếu chưa có thì tạo mới)
  • Network Setting:
    • VPC: d-vpc-002-vpc
    • Subnet: d-vpc-002-subnet-public1-us-east-1a
    • Auto-assign public IP: Enable
    • Select existing security group: d-sg-SAA-basion-host

2.3 Ceate Role SAA-PushImagesToECR-EC2Role for EC2

Để có thể push Docker image đến ECR, chúng ta cần tạo Role và gắn cho EC2

Create Role

  • Use case: EC2
  • Permissions policies: EC2InstanceProfileForImageBuilderECRContainerBuilds
  • Role name: SAA-PushImagesToECR-EC2Role

Images

Attach to Bastion host Images

2.4 Connect to EC2 and Install Docker

  • Connect to EC2 Images
  • Install Docker
    sudo yum update -y
    sudo yum -y install docker
    
  • Start Docker
    sudo service docker start
    
  • Access Docker commands in ec2-user user
    sudo usermod -a -G docker ec2-user
    sudo chmod 666 /var/run/docker.sock
    
  • docker version
    docker version
    
    Images

3. Create ECR repository and build Docker image

3.1 Create ECR Repository

Tại Console của Elastic Container Registry -> Chọn Repositories -> Create repository Images

General settings

  • Visibility settings: Private
  • Repository name: d-ecr-saa-nginx-custom

Images

3.2 Build Docker image

  • Connect to Bastion host (hoặc chạy ở local)

  • Create Custom nginx container

    mkdir nginx-app
    cd nginx-app/
    
  • Create file index.html

    index.html
    <!DOCTYPE html>
    <html>
    <head>
      <title> ECS | CloudmentorPro Blog </title>
    </head>
    <body style=text-align:center;background-color:white;font-weight:900;font-size:20px;font-family:Helvetica,Arial,sans-serif>
      <img src="https://www.docker.com/wp-content/uploads/2022/03/Moby-logo.png">
      <h1> Welcome to my custom nginx webpage hosted in a Docker container </h1>
      <p> This container was deployed: <div id="date"></div></p>
    <script>
      var date = new Date();
      document.getElementById("date").innerHTML=date.toLocaleString();
    </script>
    </body>
    </html>
    
  • Create Dockerfile

    Dockerfile
    FROM nginx:1.25.3
    COPY index.html /usr/share/nginx/html
    
    EXPOSE 80
    
    CMD ["nginx", "-g", "daemon off;"]
    
  • Build image: nginx-custom

    docker build -t nginx-custom .
    
  • Docker run

    docker run -d --name nginx -p 8080:80 nginx-custom
    
  • Confirm

    docker ps
    curl localhost:8080
    

    Images

Vậy là chúng ta đã build và test docker image xong. Tiếp theo chúng ta sẽ build và push docker image lên ECR repository

3.3 Connect to Repository

  • Tại Console ECR -> Repositories -> Click chọn d-ecr-saa-nginx-custom -> View push commands Images
  • Copy và chạy lần lượt các command Images
  1. cd nginx-app
  2. Copy command ① and run to login
  3. Copy command ② and run to build image
  4. Copy command ③ and run to tag image (có thể thay latest ở cuối command bằng một tag khác như: 20231225_1)
  5. Copy command ④ and run to push image to ECR (chú ý nếu thay latest ở ③ thì cũng thay tương tự ở command này: 20231225_1)

    Note: mỗi lần update application chúng ta sẽ tạo ra 1 docker image với tag khác nhau, và để có thể nhanh chóng roll back về image trước đó, nên việc đặt tag riêng lẻ cho các phiên bản application được recommend.

Confirm image had pushed to ECR Images

4. Create ECS Cluster

Vào Console Elastic Container Service -> Chọn Cluster -> Create cluster Images

  • Cluster configuration
    • Cluster name: d-ecs-SAA-{yourname}-cluster01

      Nhớ thay tên của mình vào chổ {yourname} vì Cluster name không được trùng nhau trong cùng Region

  • Infrastructure
    • Amazon EC2 instances: Checked
    • Auto Scaling group (ASG): Create new ASG
    • Operating system/Architecture: Amazon Linux 2023
    • EC2 instance type: t3.medium
    • Desired capacity
      • Minimum: 2
      • Maximum: 2
    • SSH Key pair: d-key-SAA-common
  • Networking
    • VPC: d-vpc-002-vpc
    • Subnets
      • d-vpc-002-subnet-private1-us-east-1a
      • d-vpc-002-subnet-private2-us-east-1b
    • Security group: Create a new security group
      • Security group name: d-sg-saa-ecs-host
      • Security group description: Allow All TCP from ALB
      • Inbound rule: Cho phép ssh từ SG của bastion host
  • Tags: Key: Name, Value: d-ecs-SAA-{cloudmentor}-cluster01

Hình ảnh minh họa Images Images Images Images Images

5. Create Task definition

Vào Console Elastic Container Service -> Task definitions -> Create new task definition

  • Task definition configuration

    • Task definition family: custom-nginx-app
  • Infrastructure requirements

    • Amazon EC2 instances: Checked
    • Operating system/Architecture: Linux/X86_64
    • Network mode: bridge
    • Task size
      • CPU: 0.25 vCPU
      • Memory: 0.25 GB
    • Task role: -
    • Task execution role: ecsTaskExcutionRole
  • Container - 1

    • Container details
      • Name: custom-nginx-app
      • Image URI: Copy URI từ ECR repository Images
  • Các Setting khác để default

Hình ảnh minh họa Images Images Images Images

6. Create Target Group

Vào EC2 Console -> Taget Group -> Nhấn Create taget group

  • Specify group details

    • Choose a target type: Instances
    • Target group name: d-tg-SAA-web-app
    • Protocol: HTTP
    • Port: 80
    • VPC: d-vpc-002-vpc
    • Tag: Key: Name Value: d-tg-SAA-web-app
    • Các setting khác để như default
    • Next
  • Register targets:

    • NOT assign instance
    • Create target group

Images

7. Create ALB

7.1 Create SG for ALB

  • Name: d-sg-SAA-ecs-alb
  • Description: Allow http from internet
  • VPC: d-vpc-002-vpc
  • Inbound rules
    TypeProtocolPort rangeSource
    HTTPTCP800.0.0.0/0
  • Outbound rules
    TypeProtocolPort rangeSource
    All trafficAllAll0.0.0.0/0
  • Tags
    Keyvalue
    Named-sg-SAA-ecs-alb

7.2 Create Application Load Balancer

Vào EC2 Console -> Load Balancers

  • Chọn create Application Load Balancer
  • Basic configuration
    • Load balancer name: d-alb-SAA-ecs-web-alb
    • Scheme: Internet-facing
    • IP address type: IPv4
  • Network mapping
    • VPC: Chọn d-vpc-002-vpc
    • Mappings:
      • Check us-east-1a -> Check ...public1...
      • Check us-east-1b -> Check ...public2...
  • Security groups: d-sg-SAA-ecs-alb
  • Listeners and routing
    • Protocol: HTTP
    • Port: 80
    • Default action: Chọn Taget group d-tg-SAA-web-server

Images

7.3 Modify SG of EC2 (Docker host)

Theo cơ chế dynamic port mapping khi chúng ta chạy nhiều task port 80 trên 2 EC2 (Docker host). Trước khi đi vào port 80 thì ALB sẽ access đến EC2 1 port được sinh ra tự động, vì chúng ta không thể biết ALB acces đến EC2 port nào nên phải Allow All TCP.

Edit Inbound Rule của SG d-sg-saa-ecs-host Images Images

8. Create ECS Service

  1. Vào Console Elastic Container Service -> Clusters -> Chọn d-ecs-SAA-{yourname}-cluster01
  2. Tại tab Services -> Create Images
  • Environment

    • Compute options: Launch type
    • Launch type: EC2
  • Deployment configuration

    • Application type: Service
    • Task definition
      • Family: custom-nginx-app
      • Revision: {No}(LATEST) (Chọn version LATEST)
    • Service name: custom-nginx-svc
    • Service type: Replica
    • Desired tasks: 3
  • Load balancing - optional

    • Load balancer type: Application Load Balancer
    • Load balancer: d-alb-SAA-ecs-web-alb
    • Listener: Use an existing listener
      • Listener: 80:HTTP
    • Target group: Use an existing target group
      • Target group name: d-tg-SAA-web-app
  • Các setting khác để default

Hình ảnh minh họa Images Images Images

Confirm 3 task đã run thành công Images

Kiểm tra Health check của các Task ở Target group Images Port cũng được sinh ra tự động (đó là lý do mình phải Edit SG của EC2 Allow All TCP từ ALB)

9. Test hoạt động

  1. Access đến DNS của Application LoadBalancer Images Images
  2. Update ECS Service Images
  3. Tăng số lượng Task lên 5 Images
  4. Quá trình scale out sẽ diễn ra nhanh chóng Images

10. Setting Route53 and access website (optional)

Để Setting Route53 trỏ domain đến Application load balancer các bạn tham khảo bài viết Configuring ALIAS record on Route 53 of AWS

Challenge

Các bạn sẽ đặt câu hỏi "Vậy làm thế nào để triển khai 1 version mới của ứng dụng?". Mình sẽ hướng dẫn cách làm ngay bây giờ.

  • Update file index.html

  • Sử dụng các command dc cung cấp ở ECR repository -> View push commands để build và push docker image

    Note: sử dụng tag mới cho docker image (tag lúc đầu là 20231225_1, thì lần build này mình sẽ change thành 20231225_2)

    Images

  • Create new Revision của Task definition, Update Image URI Images Images Images

  • Update ECS Service Images Images

  • Quá trình Deployment rolling update sẽ diễn ra bằng cách tạo ra task mới và stop task cũ. Images Images

Nhật xét

Vậy là chúng ta đã hoàn thành bài lab tạo ECS cluster, build và deploy ứng dụng trên ECS. Mặc dù mọi thứ là thủ công tuy nhiên để cho các bạn dễ hình dung và tiếp cận dễ dàng.

Trong thực tế việc Xây dựng Cluster hay Deploy sẽ triển khai tự động

  • Sử dụng IaC để xây dựng và quản lý hạ tầng
  • Sử dụng CI/CD cho việc Build và Deploy

Mình sẽ còn viết về chủ đề ECS ở những bài blog sau này!

Clean up

  1. Delete NAT Gateway
  2. Terminated Bastion host
  3. Delete ECS service
  4. Delete ECS Cluster
  5. Delete Load balancers
  6. Delete Target groups
  7. Delete ECR repo: d-ecr-saa-nginx-custom
  8. Release Elastic IP addresses
  9. Delete Role: SAA-PushImagesToECR-EC2Role
  10. Delete VPC: d-vpc-002-vpc
  11. Delete Task definition
  • Trước tiên cần Deregister tất cả các revision Images
  • Tiếp tục chọn các revision đã bị Inactive và delete Images

Bài thực hành khá dài và chắc mọi người cũng mệt rồi, pha cốc cafe + mở một bài nhạc và Relax thôi !!! Images