In this TIL note I’ll create static website hosted on AWS S3 bucket using only AWS CLI.

We will create dummy static website on bucket called happy-bunny

Create bucket

# create s3 bucket via AWS CLI
aws s3api create-bucket --bucket happy-bunny --region eu-west-1  --create-bucket-configuration LocationConstraint=eu-west-1

# ..or with profile option
aws s3api create-bucket --bucket happy-bunny --region eu-west-1  --create-bucket-configuration LocationConstraint=eu-west-1 --profile equivalent

  • --profile nameofprofil is only necesarry if you have multiple AWS accounts on your laptop (E.g work one is default and personal is equivalent)
  • to understand why the LocationConstraint read here

Set bucket public policy

create a file /tmp/bucket_policy.json with this content:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::happy-bunny/*"
        }
    ]
}

and run

aws s3api put-bucket-policy --bucket happy-bunny --policy file:///tmp/bucket_policy.json

# ..or with profile option
aws s3api put-bucket-policy --bucket happy-bunny --policy file:///tmp/bucket_policy.json --profile equivalent

Now to upload my files

cd ~/my_folder_with_static_website

aws s3 sync ./ s3://happy-bunny/

# ..or with profile option
aws s3 sync ./ s3://happy-bunny/ --profile=equivalent

# upload: ./error.html to s3://happy-bunny/error.html
# upload: ./robots.txt to s3://happy-bunny/robots.txt
# upload: ./index.html to s3://happy-bunny/index.html
# upload: ./image.png to s3://happy-bunny/image.png

static dummy website source: https://github.com/equivalent/happy-bunny-static-page

Tell AWS this should be website

aws s3 website s3://happy-bunny/ --index-document index.html --error-document error.html


# ..or with profile option
aws s3 website s3://happy-bunny/ --index-document index.html --error-document error.html  --profile equivalent

Notes:

  • s3://my-bucket/index.html will be ‘/’
  • s3://my-bucket/error.html will show on 404

Now you S3 bucket is public, set as a website and ready to go

Website will be:

<bucket-name>.s3-website.<AWS-region>.amazonaws.com

http://happy-bunny.s3-website-eu-west-1.amazonaws.com

Script

Everything together in one script

#!/bin/bash

echo '{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::happy-bunny/*"
        }
    ]
}' > /tmp/bucket_policy.json

aws s3api create-bucket --bucket happy-bunny --region eu-west-1  --create-bucket-configuration LocationConstraint=eu-west-1 --profile equivalent \
  && aws s3api put-bucket-policy --bucket happy-bunny --policy file:///tmp/bucket_policy.json --profile equivalent \
  && aws s3 sync /home/tomas/folder-where-you-keep-your-projects/happy-bunny s3://happy-bunny/  --profile equivalent \
  && aws s3 website s3://happy-bunny/ --index-document index.html --error-document error.html --profile equivalent

Sources:

Debugging

aws s3api   get-bucket-policy --bucket happy-bunny --profile equivalent
aws s3api   get-bucket-website --bucket happy-bunny --profile equivalent

Whitespace in Bucket Policy Json

An error occurred (MalformedPolicy) when calling the PutBucketPolicy operation: Policies must be valid JSON and the first byte must be '{'

Make sure the JSON in /tmp/bucket_policy.json has no leading whitespace (new line). That means:

  • this is not OK: ` { }`
  • this is not OK: \n{ }
  • this is ok {}

Bucket already exist

An error occurred (BucketAlreadyOwnedByYou) when calling the CreateBucket operation: Your previous request to create the named bucket succeeded and you already own it.

Well it already exist. Either delete it, continue with next command or create different name.

To delete the entire bucket you can use aws s3api delete-bucket --bucket happy-bunny-123 (check content inside bucket first aws s3 ls happy-bunny-123 !!!, you cannot recover it once deleted)

AWS account may have global “block public access”

If the AWS S3 bucket owner’s account has a block public access setting applied (which most accounts do by default) you may need to do some extra work in aws console:

My account also has this protection and the steps above worked. I’m just putting it here in case anyone needs it.

CORS

Custom Domain

https://blog.eq8.eu/article/custom-domain-subdomain-for-website-hosted-on-aws-s3.html

Discussion