DEV Community

Inhwa Son
Inhwa Son

Posted on

AWS Deployment Best Practices: Let's make your own SPA web app! - (1)

In this blog post, I will guide you through creating your own website from scratch and deploying it in the real world. As mentioned earlier, there are some prerequisites, as I’ll be reusing elements from my previous post:

  • An AWS account
  • An SSL-certified domain name
  • A GitHub repository for the project

Introduction

I created my web application based on this flow diagram. A more detailed explanation can be found in the README.md file in the repository.

Image description


Key Content (✅ is in this post)

  • AWS connects with GitHub ✅
  • S3 UI web hosting ✅
  • Connect with CloudFront
  • Connect CloudFront with SSL enabled domain
  • Authentication with AWS Cognito
  • Create RDS to store data
  • Create backend based on Lambdas and API Gateway
  • AWS Rekognition implementation
  • AWS Transcribe implementation

AWS connection with GitHub workflow

Since I want to update my S3 bucket whenever the UI changes, I created a workflow and connected it to my AWS account. To link GitHub with AWS, I created a new IAM user with specific policies:
Image description

Once the user is created, you will receive an access key and a secret key.
Image description

Next, you need to add these keys to GitHub Secrets.
Image description

Deploy into S3 bucket

To deploy into s3 bucket, we need to create .github/workflows/deploy.yml file from the project root.

name: Deploy to S3

on:
  push:
    branches:
      - main
    paths:
      - "**/*"

jobs:
  build_and_deploy:
    if: contains(github.event.head_commit.message, '[build]')
    runs-on: ubuntu-latest

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

    - name: Set up Node.js
      uses: actions/setup-node@v3

    - name: Install dependencies
      run: |
        npm install

    - name: Build React app
      run: |
        npm run build

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v2
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ${{ secrets.AWS_REGION }}

    - name: Validate AWS credentials
      run: |
        if aws sts get-caller-identity > /dev/null 2>&1; then
          echo "AWS credentials are valid."
        else
          echo "Error: AWS credentials are invalid or not configured."
          exit 1
        fi

    - name: Deploy to S3
      env:
        AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
        AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        AWS_REGION: ${{ secrets.AWS_REGION }}
      run: |
        aws s3 sync ./build/ s3://${{ secrets.S3_BUCKET_NAME }}/ --delete --exclude ".git/*"
Enter fullscreen mode Exit fullscreen mode

For this part; contains(github.event.head_commit.message, '[build]'), I intentionally added since I don't want to trigger too many github actions.

Enabling Web Hosting

Once deployment is complete, you can check the deployed version by enabling web hosting in S3. To do this, go to your S3 bucket, navigate to Properties tab, and select Static website hosting. After enabling it, you will receive a URL to view your deployment.

Image description

Troubleshooting

If you encounter a 403 Forbidden error, try updating the bucket policy under the Permissions tab with the following code:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::your-bucket-name/*"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

By clicking the URL, you can confirm that your code has been successfully hosted.

Image description

Top comments (0)