+1

Triển Khai Hệ Thống AWS ECS Với AWS CLI (Phần 1)

Tổng Quan

Trong bài blog này, chúng ta sẽ tìm hiểu cách triển khai một hệ thống hoàn chỉnh trên Amazon Web Services (AWS) bằng cách sử dụng Command Line Interface (CLI) của AWS. Thành phần chính của hệ thống bao gồm:

  • Application Load Balancer (ALB)
  • Amazon ECS với các instance EC2 được quản lý bởi một nhóm Auto Scaling
  • AWS Secrets Manager để lưu trữ thông tin cơ sở dữ liệu
  • Amazon RDS cho PostgreSQL

Việc sử dụng AWS CLI không chỉ mang lại trải nghiệm thú vị và hữu ích mà còn giúp bạn nắm vững các lệnh và hiểu rõ hơn về cách hoạt động của các dịch vụ AWS.

Kiến Trúc Hệ Thống

image.png

Giới Thiệu Các Dịch Vụ AWS Sử Dụng

Amazon ECS (Elastic Container Service)

  • ECS là dịch vụ quản lý containerized applications trên AWS.
  • Cho phép triển khai, quản lý và mở rộng các container Docker trên các máy chủ EC2.
  • Trong bài này, ECS sẽ quản lý các container chứa ứng dụng web của chúng ta.

Amazon RDS (Relational Database Service)

  • RDS là dịch vụ cơ sở dữ liệu quan hệ được quản lý trên AWS.
  • Cung cấp khả năng triển khai và vận hành các cơ sở dữ liệu quan hệ phổ biến như PostgreSQL, MySQL, SQL Server và Oracle.
  • Sử dụng RDS để triển khai cơ sở dữ liệu PostgreSQL cho ứng dụng của chúng ta.

Amazon ALB (Application Load Balancer)

  • ALB cung cấp phân phối tải động cho các ứng dụng chạy trên AWS.
  • Cho phép phân phối tải dựa trên nội dung của yêu cầu HTTP/HTTPS, cải thiện hiệu suất và độ tin cậy của ứng dụng.
  • Sử dụng ALB để điều hướng yêu cầu đến các container ECS chứa ứng dụng web.

AWS Secrets Manager

  • Secrets Manager là dịch vụ quản lý bảo mật cho phép lưu trữ và quản lý các bí mật như thông tin đăng nhập, khóa API và các thông tin quan trọng khác.
  • Sử dụng Secrets Manager để lưu trữ thông tin kết nối đến cơ sở dữ liệu PostgreSQL một cách an toàn.

Cài Đặt Và Cấu Hình AWS CLI

Tổng Quan

AWS CLI là công cụ cho phép bạn tương tác với các dịch vụ AWS thông qua dòng lệnh trên terminal.

Tra Cứu Lệnh AWS CLI

  • Trên Terminal: Sử dụng từ khóa help hoặc ? để tra cứu lệnh.
    • Từ khóa help: Tương tự như man page, AWS CLI sẽ cung cấp danh sách các lệnh, ý nghĩa và nhiều thông tin liên quan đến lệnh bạn cần tìm. Từ khóa help không bắt buộc đặt ở sau từ khóa aws, bạn có thể đặt ở bất kỳ vị trí nào mà bạn không biết nên viết gì. Ví dụ: aws s3 help, aws s3 ls help,…

    • Đôi khi từ khóa help cung cấp quá nhiều thông tin dư thừa, và bạn chỉ muốn tìm kiếm từ khóa mà không cần giải thích lệnh, lúc đó bạn có thể sử dụng từ khóa ?. Từ khóa ? sẽ cung cấp các từ khóa liên quan đến lệnh mà bạn đang tìm kiếm. Ví dụ: aws ?, aws s3 ?,.. Vị trí đặt từ khóa ? giống với khi sử dụng từ khóa help, tuy nhiên từ khóa ? chỉ có thể đặt ở vị trí mà đáng ra nó phải đặt một từ khóa của lệnh. Ví dụ: có thể aws s3 ? nhưng không thể aws s3 ls ?.

    • Ví dụ: aws s3 help, aws s3 ?

  • Trên Web Browser: Mặc dù rất thích thao tác với terminal nhưng mình vẫn thấy sử dụng web để tra cứu là dễ hiểu nhất. Trang tra cứu lệnh của AWS CLI cung cấp rất chi tiết về lệnh như mô tả, tùy chọn, biến, ví dụ,… rất dễ hiểu. AWS CLI Command Reference. Một mẹo khi sử dụng là sau khi tìm được lệnh, mình đi trực tiếp xuống phần ví dụ để xem cách sử dụng, sau đó mới quay lại xem các tùy chọn của nó. Hãy thử, có thể nó cũng phù hợp với bạn.

Cài Đặt AWS CLI

Dưới đây là các lệnh để cài đặt AWS CLI V2 trên Linux:

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# Xóa gói cài đặt
rm -rf awscliv2.zip aws/install
# Kiểm tra phiên bản AWS CLI
aws --version

Cấu Hình AWS CLI

Cấu hình AWS CLI với lệnh:

aws configure

Nhập các giá trị sau:

  • Access Key ID
  • Secret Access Key
  • Region
  • Default output format

Tệp cấu hình sẽ được tạo tại ~/.aws/config~/.aws/credentials. Bạn cũng có thể cấu hình thủ công bằng cách tạo các tệp này:

cat <<EOF | tee ~/.aws/config
[default]
region = ap-southeast-1
output = json
EOF

cat <<EOF | tee ~/.aws/credentials
[default]
aws_access_key_id = YOUR_ACCESS_KEY_ID
aws_secret_access_key = YOUR_SECRET_ACCESS_KEY
EOF

Kiểm Tra Cấu Hình

Kiểm tra cấu hình bằng lệnh:

aws configure list

Cấu Hình Terminal

Công Cụ JQ

jq là công cụ mạnh mẽ để xử lý dữ liệu JSON từ dòng lệnh. Cài đặt trên Ubuntu:

sudo apt install jq -y

Công Cụ Tee

tee đọc từ đầu vào tiêu chuẩn và ghi dữ liệu vào một hoặc nhiều tệp và đầu ra tiêu chuẩn. Cài đặt trên Ubuntu:

sudo apt install tee -y

Biến Môi Trường

Định nghĩa và lưu trữ các giá trị thường xuyên sử dụng qua shell variable:

project=workshop2
# global architect
region=ap-southeast-1
az_01=${region}a
az_02=${region}b
az_03=${region}c
# tags
tags='[{"Key":"purpose", "Value":"workshop2"}, {"Key":"project", "Value":"fcj_workshop"}, {"Key":"author", "Value":"pthach_cli"}]'
tags2='[{"key":"purpose", "value":"workshop2"}, {"key":"project", "value":"fcj_workshop"}, {"key":"author", "value":"pthach_cli"}]'
tagspec='{Key=purpose,Value=workshop2},{Key=project,Value=fcj_workshop},{Key=author,Value=pthach_cli}]'
# Identity
aws_account_id=$(aws sts get-caller-identity --query 'Account' --output text)
# ecr
docker_image_name=container-image
ecr_image_uri=$aws_account_id.dkr.ecr.$region.amazonaws.com/${docker_image_name}:latest

Các biến này bao gồm thông tin về bài lab, vùng & AZ, tags, ID tài khoản AWS, và thông tin ECR.

Tạo Instance Profile cho EC2

Tổng quan

AWS Instance Profile là một cách để gán IAM (Identity and Access Management) Role cho các EC2 Instances. Nó cho phép các EC2 Instances truy cập các dịch vụ AWS một cách an toàn và bảo mật, mà không cần sử dụng các thông tin đăng nhập truyền thống như Access Key ID và Secret Access Key.

Lưu ý: Khi tạo IAM Role cho EC2 sử dụng AWS console, một instance profile sẽ được tạo tự động và nó có tên giống như IAM role. Nếu cấu hình EC2 sử dụng AWS console thì bạn sẽ chọn IAM Role (hiển thị) thay vì IAM instance profile (nhưng vẫn danh sách role vẫn dựa trên danh sách instance profile). Nhưng nếu Sử dụng AWS CLI, API hoặc AWS SDK thì việc tạo IAM Role, Instance Profile là 2 quá trình riêng biệt. Nếu cấu hình IAM EC2 thì bạn sẽ chọn instance profile name.

Quy Trình

Các bước để tạo 1 instance profile:

  1. Tạo IAM Role với quyền được sử dụng bởi EC2.

    ecs_instance_role_name=$project-ecs-instance-role
    # Create EC2 Role
    aws iam create-role \
        --role-name $ecs_instance_role_name \
        --assume-role-policy-document '{
            "Version": "2012-10-17",
            "Statement": [{
                "Effect": "Allow",
                "Principal": {
                    "Service": ["ec2.amazonaws.com"]
                },
                "Action": ["sts:AssumeRole"]
            }]
        }' \
        --tags "$tags"
    
  2. Xác định các API actions và resources mà Instance có thể sử dụng (Gán policy cho IAM Role)

    aws iam attach-role-policy \
        --policy-arn arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role \
        --role-name $ecs_instance_role_name
    
    aws iam attach-role-policy \
        --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore \
        --role-name $ecs_instance_role_name
    
  3. Tạo IAM instance profile

    aws iam create-instance-profile \
        --instance-profile-name $ecs_instance_role_name
    
  4. Thêm Role vừa được tạo vào Instance profile

    aws iam add-role-to-instance-profile \
        --instance-profile-name $ecs_instance_role_name \
        --role-name $ecs_instance_role_name
    
  5. Lấy thông tin Instance Profile sử dụng cho instance (EC2)

    ecs_instance_profile_arn=$(aws iam get-instance-profile \
        --instance-profile-name $ecs_instance_role_name \
        --output text \
        --query 'InstanceProfile.Arn')
    

Tạo EC2 Keypair

Tổng quan

A key pair, consisting of a public key and a private key, is a set of security credentials that you use to prove your identity when connecting to an Amazon EC2 instance.

Nói cách khác thì AWS Key Pair chính là 1 cặp khóa public và private của ssh key. Có thể được tạo bởi AWS (cách chúng ta sẽ làm) hoặc bạn tự tạo thông qua lệnh tạo key của ssh ssh-keygen rồi upload lên AWS. Lúc này AWS sẽ giúp bạn thêm phần public key vào trong thư mục ~/.ssh của đúng instance mà bạn sử dụng.

Quy trình

Lệnh dưới đây được sử dụng để tạo keypair EC2

Tạo keypair bằng lệnh aws ec2 create-key-pair. Lệnh này sẽ trả về nội dung của tệp key, sau đó lưu nó vào một tệp có định dạng *.pem để sử dụng sau này.

Tuy nhiên, để sử dụng file key này thì phải cấu hình quyền

chmod 400 key.pem

❓ Tại sao phải chmod 400
Khi kết nối vào một instance EC2 qua SSH, tệp khóa riêng tư (*.pem) cần có quyền truy cập được cài đặt chặt chẽ để đảm bảo an ninh (1 trong những điều kiện để trở thành ssh key là chỉ cho phép owner truy cập và sử dụng). Lệnh chmod 400 key.pem đặt quyền của tệp khóa thành chỉ có thể đọc được bởi chủ sở hữu (400 = 100 000 000), đảm bảo rằng không có người dùng nào khác trên hệ thống có thể truy cập được nó (ngoại trừ root user 😁 và owner). Điều này là cần thiết vì SSH sẽ từ chối sử dụng một tệp khóa riêng tư mà người dùng khác có thể truy cập.

ecs_instance_key_name=$project-keypair
# Tạo keypair
aws ec2 create-key-pair \
    --key-name $ecs_instance_key_name \
    --region $region \
    --tag-specifications `echo 'ResourceType=key-pair,Tags=['$tagspec` \
    --query 'KeyMaterial' \
    --output text > ./$ecs_instance_key_name.pem

Tạo Elastic Container Registry

Tổng quan

Amazon Elastic Container Registry (ECR) là dịch vụ quản lý và lưu trữ các container images cho việc sử dụng với Amazon ECS, Amazon EKS, hoặc các dịch vụ khác sử dụng Docker containers. Trong phần này, chúng ta sẽ tìm hiểu cách tạo và quản lý một repository ECR trên AWS. {{% /notice %}}

AWS cung cấp 2 loại ECR repository là public và private. Nhưng trong bài lab mình chỉ làm việc với public ECR repository. Muốn tìm hiểu thêm về ECR Private Repository thì tham khảo tại Amazon ECR private repositories

Quy trình

Trong phần này, chúng ta đã tạo một ECR repository, đăng nhập vào ECR từ AWS CLI, push một image lên ECR, và pull một image từ ECR.

  1. Tạo một ECR Repository

    ecr_name=$docker_image_name
    # Tạo repository ECR mới
    aws ecr create-repository \
        --repository-name $ecr_name \
        --region $region \
        --tags "$tags"
    
  2. Xác thực đối với ECR: chúng ta cần xác thực đăng nhập vào ECR từ AWS CLI để có thể thao tác với image trên repository.

    Sử dụng lệnh sau để xác thực với public registry (private registry sẽ sử dụng cách khác)

    aws ecr get-login-password \
        --region $region \
        | docker login \
        --username AWS \
        --password-stdin $aws_account_id.dkr.ecr.$region.amazonaws.com
    

    Sau khi xác thực thành công có thể kiểm tra thông tin xác thực trong file ~/.docker/config.json. Sử dụng lệnh

    # Kiểm tra tệp config Docker
    cat ~/.docker/config.json
    
  3. Source code Download Source

    Source code là một project có tên workshop được viết bằng Java Spring Boot 3 kết hợp với Maven chạy trên cổng 8080, bao gồm 2 phương thức:

    • GET /api/product: Hiển thị danh sách sản phẩm.
    • POST /api/product: Thêm sản phẩm vào danh sách. Sử dụng PostgreSQL là database và sử dụng 5 biến môi trường để kết nối đến database là POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DB, POSTGRES_USERNAME, và POSTGRES_PASSWORD.
  4. Tạo Docker image từ source code

    Đến thư mục chứa source code (giải nén bằng lênh unzip workshop.zip)

    docker build -t $ecr_name .
    # Kiểm tra Docker image đã được tạo đúng chưa
    docker images --filter reference=$ecr_name
    

    Lệnh docker build dùng để tạo docker image, lệnh docker images --filter dùng để kiểm tra xem docker image đã được tạo hay chưa.

  5. Đặt tag cho image: Để có thể push docker image lên ECR, image phải được đặt tag với định dạng aws_account_id.dkr.ecr.region.amazonaws.com/ecr_repository_name.

    # Đặt tag cho image để push vào repository của bạn.
    docker tag $ecr_name:latest $aws_account_id.dkr.ecr.$region.amazonaws.com/$ecr_name
    
  6. Sử dụng lệnh sau để push image lên ECR

    # Push to AWS ECR repository
    docker push $aws_account_id.dkr.ecr.$region.amazonaws.com/$ecr_name
    
  7. Pull image từ ECR: Để pull một image từ ECR, bạn cần chỉ định đúng địa chỉ của repository ECR và tag của image cần pull.

    # Pull image từ ECR
    docker pull $aws_account_id.dkr.ecr.$region.amazonaws.com/$ecr_name:latest
    

Tạo Mạng

Tổng quan

VPC thì chắc không cần phải giới thiệu nhiều rồi, đây là dịch vụ mạng của AWS.

Một bài viết khá hay của AWS Study Group về network trên AWS mà bạn nên đọc để hiểu thêm về phần này Bài 3: Các dịch vụ mạng trên AWS – Phần 1: Khái niệm VPCS

Trong phần này chúng ta sẽ tạo 1 VPC với 6 subnet (3 private và 3 public nằm ở 3 available zone của region singapore), 1 Internet Gateway và 1 Route Table.

Quy trình

  1. Tạo VPC

    # network
    vpc_cidr=10.1.0.0/16
    vpc_name=$project-vpc
    # Tạo VPC và Bật tính năng dns-hostname trong VPC
    vpc_id=$(aws ec2 create-vpc \
        --cidr-block $vpc_cidr \
        --region $region \
        --tag-specifications `echo 'ResourceType=vpc,Tags=[{Key=Name,Value='$vpc_name'},'$tagspec` \
        --output text \
        --query 'Vpc.VpcId')
    
    aws ec2 modify-vpc-attribute \
        --vpc-id $vpc_id \
        --enable-dns-hostnames '{"Value": true}'
    
    echo vpc_id=$vpc_id
    
  2. Tạo Subnet

    Tạo 6 subnet, bao gồm 3 subnet riêng tư và 3 subnet công cộng chia ra cho 3 AZ a, b, c của khu vực Singapore (ap-southeast-1).

    1. Tạo Public Subnet

      • public subnet 1=10.1.0.0/20
      • public subnet 2=10.1.16.0/20
      • public subnet 3=10.1.32.0/20
      
      
      for (( i=1; i<=3; i++ ))
      do
          eval pubsubnet${i}_cidr=\"10.1.$((($i-1)*16)).0/20\"
      done
      echo pubsubnet1_cidr=$pubsubnet1_cidr
      echo pubsubnet2_cidr=$pubsubnet2_cidr
      echo pubsubnet3_cidr=$pubsubnet3_cidr
      
      pubsubnet1_name=$project-pubsubnet-$az_01
      pubsubnet2_name=$project-pubsubnet-$az_02
      pubsubnet3_name=$project-pubsubnet-$az_03
      # Tạo public subnet
      subnet_public_1=$(aws ec2 create-subnet \
          --availability-zone $az_01 \
          --cidr-block $pubsubnet1_cidr \
          --tag-specifications `echo 'ResourceType=subnet,Tags=[{Key=Name,Value='$pubsubnet1_name'},'$tagspec` \
          --vpc-id $vpc_id | jq -r '.Subnet.SubnetId')
      
      subnet_public_2=$(aws ec2 create-subnet \
          --availability-zone $az_02 \
          --cidr-block $pubsubnet2_cidr \
          --tag-specifications `echo 'ResourceType=subnet,Tags=[{Key=Name,Value='$pubsubnet2_name'},'$tagspec` \
          --vpc-id $vpc_id | jq -r '.Subnet.SubnetId')
      
      subnet_public_3=$(aws ec2 create-subnet \
          --availability-zone $az_03 \
          --cidr-block $pubsubnet3_cidr \
          --tag-specifications `echo 'ResourceType=subnet,Tags=[{Key=Name,Value='$pubsubnet3_name'},'$tagspec` \
          --vpc-id $vpc_id | jq -r '.Subnet.SubnetId')
      
      echo subnet_public_1=$subnet_public_1
      echo subnet_public_2=$subnet_public_2
      echo subnet_public_3=$subnet_public_3
      
    2. Tạo Private Subnet

      • private subnet 1=10.1.128.0/20
      • private subnet 2=10.1.144.0/20
      • private subnet 3=10.1.160.0/20
      for (( i=1; i<=3; i++ ))
      do
          eval prisubnet${i}_cidr=\"10.1.$((($i+3)*16)).0/20\"
      done
      echo prisubnet1_cidr=$prisubnet1_cidr
      echo prisubnet2_cidr=$prisubnet2_cidr
      echo prisubnet3_cidr=$prisubnet3_cidr
      prisubnet1_name=$project-prisubnet-$az_01
      prisubnet2_name=$project-prisubnet-$az_02
      prisubnet3_name=$project-prisubnet-$az_03
      # Tạo private subnet
      subnet_private_1=$(aws ec2 create-subnet \
          --availability-zone $az_01 \
          --cidr-block $prisubnet1_cidr \
          --tag-specifications `echo 'ResourceType=subnet,Tags=[{Key=Name,Value='$prisubnet1_name'},'$tagspec` \
          --vpc-id $vpc_id | jq -r '.Subnet.SubnetId')
      
      subnet_private_2=$(aws ec2 create-subnet \
          --availability-zone $az_02 \
          --cidr-block $prisubnet2_cidr \
          --tag-specifications `echo 'ResourceType=subnet,Tags=[{Key=Name,Value='$prisubnet2_name'},'$tagspec` \
          --vpc-id $vpc_id | jq -r '.Subnet.SubnetId')
      
      subnet_private_3=$(aws ec2 create-subnet \
          --availability-zone $az_03 \
          --cidr-block $prisubnet3_cidr \
          --tag-specifications `echo 'ResourceType=subnet,Tags=[{Key=Name,Value='$prisubnet3_name'},'$tagspec` \
          --vpc-id $vpc_id | jq -r '.Subnet.SubnetId')
      
      echo subnet_private_1=$subnet_private_1
      echo subnet_private_2=$subnet_private_2
      echo subnet_private_3=$subnet_private_3
      
  3. Tạo Internet Gateway

    Các thành phần trong mạng cần truy cập Internet phải đi qua Internet Gateway. Các lệnh sau giúp tạo một Internet Gateway và gắn nó vào VPC đã được tạo trước đó:

    igw_name=$project-igw
    # Tạo Internet Gateway
    gateway_id=$(aws ec2 create-internet-gateway \
        --region $region \
        --tag-specifications `echo 'ResourceType=internet-gateway,Tags=[{Key=Name,Value='$igw_name'},'$tagspec` \
        --output text \
        --query 'InternetGateway.InternetGatewayId')
    
    aws ec2 attach-internet-gateway \
        --vpc-id $vpc_id \
        --internet-gateway-id $gateway_id
    
    echo gateway_id=$gateway_id
    
  4. Create Route Table and Routing

    Ở bước trước, chúng ta đã tạo 3 Public Subnet, nhưng hiện tại, các Public Subnet này không thể kết nối đến internet. Để các Public Subnet này trở thành Public Subnet thực sự thì chúng cần phải kết nối chúng với Internet Gateway thông qua Route Table.

    Vậy thì Route Table của private subnet đâu? private table lúc này sẽ sử dụng default Route Table được tạo với AWS. Thế nếu không sử dụng Default Route Table thì sao? thì phải tạo 1 Route Table

    1. Create Public Routable

      Các lệnh sau đây giúp các public subnet kết nối đến internet gateway. Có 3 lệnh chính là

      • aws ec2 create-route-table: tạo Route Table
      • aws ec2 create-role: kết nối Route Table với Internet Gateway
      • aws ec2 associate-route-table: kết nối Route Table với Subnet
      rtb_name=$project-rtb-public
      # Tạo Route table
      rtb_public_id=$(aws ec2 create-route-table \
          --tag-specifications `echo 'ResourceType=route-table,Tags=[{Key=Name,Value='$rtb_name'},'$tagspec` \
          --vpc-id $vpc_id | jq -r '.RouteTable.RouteTableId')
      
      aws ec2 create-route \
          --route-table-id $rtb_public_id \
          --destination-cidr-block 0.0.0.0/0 \
          --gateway-id $gateway_id
      
      # Gán mỗi Public Subnet với the Route Table
      aws ec2 associate-route-table \
          --subnet-id $subnet_public_1 \
          --route-table-id $rtb_public_id
      
      aws ec2 associate-route-table \
          --subnet-id $subnet_public_2 \
          --route-table-id $rtb_public_id
      
      aws ec2 associate-route-table \
          --subnet-id $subnet_public_3 \
          --route-table-id $rtb_public_id
      
      echo rtb_public_id=$rtb_public_id
      
    2. Private Route Table

      rtb_name=$project-rtb-private
      echo rtb_name=$rtb_name
      # Tạo Route table
      rtb_private_id=$(aws ec2 create-route-table \
          --tag-specifications `echo 'ResourceType=route-table,Tags=[{Key=Name,Value='$rtb_name'},'$tagspec` \
          --vpc-id $vpc_id | jq -r '.RouteTable.RouteTableId')
      
      # Gán mỗi Public Subnet với the Route Table
      aws ec2 associate-route-table \
          --subnet-id $subnet_private_1 \
          --route-table-id $rtb_private_id
      
      aws ec2 associate-route-table \
          --subnet-id $subnet_private_2 \
          --route-table-id $rtb_private_id
      
      aws ec2 associate-route-table \
          --subnet-id $subnet_private_3 \
          --route-table-id $rtb_private_id
      
      echo rtb_private_id=$rtb_private_id
      

Tạo Security Group

Tổng quan

Security Group hoạt động như là một tưởng lửa ảo dành cho EC2 instance nhằm kiểm soát lưu lượng vào và ra.

Một bài viết khá hay của AWS Study Group liên quan đến Security Group mà bạn nên đọc để hiểu thêm về phần này Bài 4: Các dịch vụ mạng trên AWS – Phần 2: AWS Security Groups với AWS Network Access Control List (NACL)

Ở phần này, Chúng ta lần lượt sẽ tạo Security Group cho EC2 Instance, RDS và ALB.

Quy trình

  1. Tạo Security Group cho Instance

    Trong phần này, chúng ta tạo một Security Group cho các Instance. Mục đích của Security Group này là đảm bảo rằng các bên được phép truy cập vào instance chỉ qua các cổng được chọn.

    ecs_instance_sgr_name=$project-ecs-sgr
    # Tạo Security Group
    ecs_instance_sgr_id=$(aws ec2 create-security-group \
       --group-name $ecs_instance_sgr_name \
       --description "Security group for EC2 in ECS" \
       --tag-specifications `echo 'ResourceType=security-group,Tags=[{Key=Name,Value='$ecs_instance_sgr_name'},'$tagspec` \
       --vpc-id $vpc_id | jq -r '.GroupId')
    
    aws ec2 authorize-security-group-ingress \
       --group-id $ecs_instance_sgr_id \
       --protocol tcp \
       --port 8080 \
       --cidr 0.0.0.0/0
    
    aws ec2 authorize-security-group-ingress \
       --gr  oup-id $ecs_instance_sgr_id \
       --protocol tcp \
       --port 22 \
       --cidr 0.0.0.0/0
    
    aws ec2 authorize-security-group-ingress \
       --group-id $ecs_instance_sgr_id \
       --protocol tcp \
       --port 443 \
       --cidr 0.0.0.0/0
    
    echo ecs_instance_sgr_id=$ecs_instance_sgr_id
    

    Trong mã trên:

    • ecs_instance_sgr_name: Đây là tên của Security Group cho các Instance, được tạo ra dựa trên biến $project.
    • aws ec2 create-security-group: Dòng này tạo một Security Group mới với tên và mô tả được chỉ định.
    • aws ec2 authorize-security-group-ingress: Các dòng này mở các cổng (port) cụ thể cho Security Group. Cụ thể là port 8080 (sử dụng cho ứng dụng), port 22 (sử dụng cho SSH), và port 443 (sử dụng cho các dịch vụ AWS : VPC endpoint,..).
    • echo ecs_instance_sgr_id=$ecs_instance_sgr_id: Dòng này in ra ID của Security Group mới được tạo.
  2. Tạo Security Group cho RDS

    Trong phần này, chúng ta tạo một Security Group cho Relational Database Service (RDS). Mục đích của Security Group này là cho phép các Instance kết nối tới cổng sử dụng cho PostgreSQL.

    rds_sgr_name=$project-rds-sgr
    # Tạo Security Group
    rds_sgr_id=$(aws ec2 create-security-group \
       --group-name $rds_sgr_name  \
       --description "Security group for RDS" \
       --tag-specifications `echo 'ResourceType=security-group,Tags=[{Key=Name,Value='$rds_sgr_name'},'$tagspec` \
       --vpc-id $vpc_id | jq -r '.GroupId')
    
    aws ec2 authorize-security-group-ingress \
       --group-id $rds_sgr_id \
       --protocol tcp \
       --port 5432 \
       --source-group $ecs_instance_sgr_id
    
    echo rds_sgr_id=$rds_sgr_id
    

    Trong mã trên:

    • rds_sgr_name: Đây là tên của Security Group cho RDS, dựa trên biến $project.
    • aws ec2 create-security-group: Dòng này tạo một Security Group mới cho RDS với các thông tin như tên và mô tả được chỉ định.
    • aws ec2 authorize-security-group-ingress: Dòng này cho phép các kết nối đến cổng 5432 (sử dụng cho PostgreSQL) từ Instance được chỉ định bởi $ecs_instance_sgr_id.
    • echo rds_sgr_id=$rds_sgr_id: Dòng này in ra ID của Security Group cho RDS.
  3. Tạo Security Group for ALB

    Trong phần này, chúng ta tạo một Security Group cho Application Load Balancer (ALB). Mục đích của Security Group này là cho phép người dùng kết nối tới cổng sử dụng cho HTTP.

    alb_sgr_name=$project-alb-sgr
    # Tạo Security Group
    alb_sgr_id=$(aws ec2 create-security-group \
       --group-name $alb_sgr_name \
       --description "Security group for ALB" \
       --tag-specifications `echo 'ResourceType=security-group,Tags=[{Key=Name,Value='$alb_sgr_name'},'$tagspec` \
       --vpc-id $vpc_id | jq -r '.GroupId')
    
    aws ec2 authorize-security-group-ingress \
       --group-id $alb_sgr_id \
       --protocol tcp \
       --port 22 \
       --cidr 0.0.0.0/0
    
    aws ec2 authorize-security-group-ingress \
       --group-id $alb_sgr_id \
       --protocol tcp \
       --port 80 \
       --cidr 0.0.0.0/0
    
    echo alb_sgr_id=$alb_sgr_id
    

    Trong mã trên:

    • alb_sgr_name: Đây là tên của Security Group cho ALB, dựa trên biến $project.
    • aws ec2 create-security-group: Dòng này tạo một Security Group mới cho ALB với các thông tin như tên và mô tả được chỉ định.
    • aws ec2 authorize-security-group-ingress: Dòng này cho phép các kết nối đến cổng 80 (sử dụng cho HTTP) từ mọi nơi (0.0.0.0/0)

Kết thúc phần 1

Phần này mình chủ yếu chuẩn bị và cài đặt các dịch vụ cần thiết để chuẩn bị cho phần 2, nơi mình sẽ trực tiếp triển khai ứng dụng lên ECS. Trong phần tiếp theo, mình sẽ triển khai các dịch vụ chính bao gồm RDS, SecretsManager, ALB, và ECS.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí