DEV Community

Inhwa Son
Inhwa Son

Posted on • Edited on

Secure Your Website: Best Practices for AWS Deployment

Introduction

In this post, I’ll share my perspective on securely deploying a simple web page, based on key principles I’ve learned from cloud computing in the fall of 2024. When discussing "security" in web development, there are numerous aspects to consider, but I’ll focus on four critical areas:

  1. Dockerization
  2. CI/CD Pipeline
  3. Running on ECS Fargate
  4. SSL-Enabled Domain

Additionally, I’ll demonstrate how to set up the website to be Highly Available (HA), ensuring reliability and uptime even during traffic spikes or failures.

Before we start

I am using this repository to create simple front, back, and nginx architecture.
https://github.com/inhwaS/supreme
Image description


1. Dockerization

Containerizing the application ensures consistency across different environments, which is essential for security.

In the repository, I created a docker-compose.yml file to run all containers under the same network. However, nginx is only mapped to port 80 for HTTP, while the demo(backend) and front(frontend) are only exposing their respective folders, allowing communication solely within the same bridge network.

supreme/
├── README.md
├── docker-compose.yml
├── demo/
│   └── Dockerfile
├── front/
│   └── Dockerfile
└── nginx/
    └── Dockerfile
Enter fullscreen mode Exit fullscreen mode

2. CI/CD Pipeline

Automating the deployment process, from building a Docker image to pushing it into Amazon ECR (Elastic Container Registry), reduces human error and improves security.

Under the .github/workflows folder, I created a release.yml file to automate the pipeline for pushing Docker images into the ECR repository. Since I’m using an AWS Academy account, it’s mandatory to include the AWS_SESSION_TOKEN.

name: Release

on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Log in to Amazon ECR
        uses: aws-actions/amazon-ecr-login@v1
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_SESSION_TOKEN: ${{ secrets.AWS_SESSION_TOKEN }}
          AWS_REGION: ${{ secrets.AWS_REGION }}

      - name: Build and push Docker images
        env:
          AWS_REGION:  ${{ secrets.AWS_REGION }}
          ECR_REPO_NAME_BACKEND: supreme-backend
          ECR_REPO_NAME_FRONTEND: supreme-frontend
          ECR_REPO_NAME_NGINX: supreme-nginx
          IMAGE_TAG: latest
          ACCOUNT_ID: ${{ secrets.ACCOUNT_ID }}
        run: |
          # Full ECR repository URIs
          ECR_URI_BACKEND="${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPO_NAME_BACKEND}"
          ECR_URI_FRONTEND="${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPO_NAME_FRONTEND}"
          ECR_URI_NGINX="${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPO_NAME_NGINX}"

          # Build images for both architectures
          echo "Building multi-architecture Docker images..."
          docker buildx build --platform linux/amd64,linux/arm64 -t ${ECR_URI_BACKEND}:${IMAGE_TAG} --push ./demo
          docker buildx build --platform linux/amd64,linux/arm64 -t ${ECR_URI_FRONTEND}:${IMAGE_TAG} --push ./front
          docker buildx build --platform linux/amd64,linux/arm64 -t ${ECR_URI_NGINX}:${IMAGE_TAG} --push ./nginx

Enter fullscreen mode Exit fullscreen mode

After writing the file, I stored the relevant keys in the GitHub settings.

Image description

Whenever a commit is pushed to the master branch, it automatically builds the Docker image and pushes it to the ECR repository that I have already set up. To create ECR, please refer this tutorial.
Image description
When the build is done,
Image description
we can confirm that ECR is updated with new images.
Image description


3. Running on ECS Fargate

Utilizing Amazon’s ECS Fargate allows the application to run securely in a serverless environment, with built-in scaling and isolation.

With the image stored in ECR, we can create a Task Definition to run ECS services. Based on my repository, it will create three different containers.

Image description

Image description
After successfully creating all the containers, we can access the nginx container using the assigned IP for that container, and they communicate successfully.

Image description

Image description


4. SSL-Enabled Domain

Configuring a custom domain with SSL ensures encrypted communication between the user and the website, enhancing trust and security.

To use my personal domain, I tried using name.com since it offers two free domain names under the GitHub Student Developer Pack.

Image description

I registered dragonai.live and stored my SSL certificate in ACM.

Image description

I also wrote how to issue name.com domain here in Korean.

After properly setting up the load balancer for my ECS services, I was able to create a secure website with a valid SSL certificate.

Image description

Image description


High Available (HA) Website

To ensure high availability for my website, I need to host servers in different availability zones in AWS. Since I'm running my containers on ECS, I had to configure IP instances accordingly.

Since this involves a lot of steps, I would like to recommend a prompt for GenAI that I can use to get successful instructions from ChatGPT.

I'm looking to set up a highly available website on AWS using ECS and other AWS services. I already have my SSL-certified domain name. Could you provide a step-by-step guide that includes:

1. Creating a VPC
2. Setting up load balancers
3. Deploying a container with that load balancer in ECS
4. Connecting my domain to the ECS service

Enter fullscreen mode Exit fullscreen mode

My load balancer looks like this:
Image description

Image description


Conclusion:

This blog post may not be very beginner-friendly, as it covers many different concepts. However, I believe the most challenging part will be creating a "Highly Available" website, for which I provided a prompt. I outlined some mandatory steps from a security perspective, so for detailed instructions, you can seek help from GenAI and follow the steps they provide. While it does require a basic understanding of web architecture, if you start following the steps I outlined and ask for details from GenAI, you'll be able to run a "secure website" on your own.

Thank you for reading, and cheers!

Top comments (0)