Transferring a static website from DigitalOcean to AWS


I’ve been hosting a static site on DigitalOcean for some time. While it used to be free, I’ve now exhausted my resources and am currently billed $5 a month by DigitalOcean. Although this cost is minimal, Id really like to consolidate my side projects into one platform.

DigitalOcean offers an uncomplicated method to deploy React/static apps with auto GitHub deployment (which I highly recommend to anyone looking for a simple/easy solution) here. However, if you desire greater control and an even more cost-effective solution, AWS’s S3 and Cloudfront are great choices. AWS’s S3 bucket provides 5GB of free storage, and Cloudfront offers 1TB of free data transfer. This means we can reduce cost significantly for a small static website.

Create S3 bucket

Setting up an S3 bucket is straightforward:

  1. Navigate to AWS S3 and choose Create Bucket.
  2. Name the bucket: I recommend using a name similar to your domain, such as <MY-DOMAIN>.com.
  3. Choose or note the bucket’s region: For instance, my default is set to us-east-1.

For now, that’s all for the bucket setup. We’ll adjust permissions later based on Cloudfront’s requirements.

Ensure the following default settings are maintained:

  • ACL Disabled
  • Block All public access
  • Bucket versioning disabled
  • No Tags
  • Server-side encryption with Amazon S3 managed keys (SSE-S3) selected
  • Bucket Key enabled

Create Cloudfront Distribution

  1. Navigate to AWS Cloudfront and choose Create Distribution.
  2. When prompted for an Origin domain, select the S3 bucket you created.
  3. For Origin access, choose Origin access control settings (recommended).
  4. Create a control setting by clicking on the Create control setting button. You can leave the defaults or add a description if desired.
  5. Under Viewer protocol policy, I prefer to select “Redirect HTTP to HTTPS”.
  6. For Default root object - optional, specify your site’s root file. Typically, this is “index.html”, but it could differ based on your site’s structure.

Once the distribution is created at the top of the browser it will ask you to copy the policies for the S3 bucket. Select copy and go back into your S3 bucket.

In your S3 bucket go to the bucket Permissions.

Edit your Bucket policy

It should look something like this

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "AllowCloudFrontServicePrincipal",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<BUCKET_NAME>/*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::<CLOUDFRONT_DISTRABUTION_ID>:distribution/<CLOUDFRONT_DISTRABUTION_ID>"
                }
            }
        }
    ]
}

Create IAM User

  1. Navigate to the IAM management console in AWS.
  2. Click on Create user.
  3. Skip the option Provide user access to the AWS Management Console - optional.
  4. On the Permissions options page, choose Attach policies directly. This will allow the user specific access permissions needed for deployment.
  5. Add AmazonS3FullAccess and CloudFrontFullAccess (this probably isn’t the most secure if you are worried about super tight security.
  6. Once the user is created you will want to create an access key. Go back into the user that was created and select the Security credentials tab select Create access key under the Access keys section. Select the use case I used Third-party service add a tag if desired. Download the csv or copy the actions to your clipboard. If you don’t download the csv or temporarily save these keys you will need to go through this process again

Create Github repo

If you’re reading this guide, I assume you’re familiar with creating GitHub repositories. If not, GitHub offers comprehensive documentation here.

Update Github action secrets

To secure your AWS credentials, use GitHub’s secrets management. Navigate to your GitHub repository’s settings, find the “Secrets” section, and add your AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.

Update Github actions

For deployment, create a GitHub action in your repo. I typically name it deploy.yml, but you can choose another name if you prefer.

name: Deploy to AWS

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

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

      - name: Build React App
        run: |
          npm install
          npm run build

      - name: Deploy to S3
        uses: jakejarvis/s3-sync-action@master
        with:
          args: --follow-symlinks --delete
        env:
          AWS_S3_BUCKET: <BUCKET_NAME>
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_REGION: 'us-east-1' # change this to your AWS region
          SOURCE_DIR: 'build'

      - name: Invalidate CloudFront Distribution
        uses: chetan/invalidate-cloudfront-action@v1.3
        with:
          distribution: <CLOUDFRONT_DISTRABUTION_ID>
          paths: '/*'
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_REGION: 'us-east-1' # change this to your preferred AWS region
          DISTRIBUTION: <CLOUDFRONT_DISTRABUTION_ID>
          PATHS: '/*'
edited Apr 18, 2026