← All posts
2 min read

Host a static website on S3 using only CLI

#aws#s3#web#cli
📑 On this page

Part 7 of AWS from Zero. Today we host a tiny static website on S3 using only CLI commands.

This is a learning exercise, not a full production setup. Production sites usually add CloudFront, HTTPS, caching, redirects, logging, and stricter deployment workflows.

Create the site files

mkdir aws-zero-site
cd aws-zero-site

Create index.html:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>AWS from Zero</title>
  </head>
  <body>
    <h1>Hello from S3</h1>
    <p>This page was deployed using AWS CLI.</p>
  </body>
</html>

Create error.html:

<!doctype html>
<html>
  <body>
    <h1>Not found</h1>
  </body>
</html>

Create the bucket

BUCKET="aws-zero-site-dhayal-20260713"
REGION="ap-south-1"
aws s3api create-bucket \
  --bucket "$BUCKET" \
  --region "$REGION" \
  --create-bucket-configuration LocationConstraint="$REGION"

Enable website hosting

aws s3api put-bucket-website \
  --bucket "$BUCKET" \
  --website-configuration '{
    "IndexDocument": { "Suffix": "index.html" },
    "ErrorDocument": { "Key": "error.html" }
  }'

Allow public reads

New S3 buckets block public access by default. For this website demo, we intentionally remove that block and attach a read-only public policy.

aws s3api delete-public-access-block --bucket "$BUCKET"

Create policy.json:

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

Replace the bucket name:

sed -i "s/REPLACE_BUCKET_NAME/$BUCKET/g" policy.json

PowerShell:

(Get-Content policy.json) -replace "REPLACE_BUCKET_NAME", $BUCKET | Set-Content policy.json

Apply it:

aws s3api put-bucket-policy \
  --bucket "$BUCKET" \
  --policy file://policy.json

Upload the website

aws s3 sync . "s3://$BUCKET/" --exclude "policy.json"

Website endpoint:

echo "http://$BUCKET.s3-website.$REGION.amazonaws.com"

Open that URL in a browser.

Cleanup

aws s3 rm "s3://$BUCKET/" --recursive
aws s3api delete-bucket-policy --bucket "$BUCKET"
aws s3api delete-bucket-website --bucket "$BUCKET"
aws s3api delete-bucket --bucket "$BUCKET" --region "$REGION"

In part 8, we launch our first EC2 instance from the CLI.