Introduction
The objective of this guide is to walk through the process of setting up a static website and creating redirects using Amazon Web Services (AWS). This involves the following steps:
- Registering and setting up a domain using Route 53.
- Creating an SSL certificate using ACM.
- Setting up a storage bucket on Amazon S3.
- Configuring Amazon CloudFront for content delivery.
- Redirecting certain paths to other URLs.
Instructions
Set up Domain with Route 53
Register or transfer your domain to Route 53.
Once the domain is in Route 53, create a hosted zone for the domain.
Make note of the NS records AWS assigns to your domain, you'll need these later.
aws route53 create-hosted-zone --name example.com --caller-reference 2023-06-14-01
If transferring or migrating from a different service please refer to this document.
Create SSL certificate with Amazon Certificate Manager (ACM)
In the ACM console, request a public certificate.
Input your domain name and validate ownership, either through DNS validation or email validation. If your domain is already in Route 53, DNS validation can be done automatically.
Once validated, the certificate is issued. Note down the ARN (Amazon Resource Name) for the certificate.
This process is not typically done through CLI due to the complexity of the certificate validation process.
Set up Amazon S3 bucket and enable Static Hosting
Create a new S3 bucket with the same name as your domain and enable static website hosting on the bucket. Set "index.html" as the index document.
Use the following commands:
aws s3 mb s3://example.com --region us-west-2
aws s3 website s3://example.com/ --index-document index.html
Create a bucket policy file bucketpolicy.json
to enable public read (Alternatively, you can access S3 from AWS Management Console and turn off “Block all public access” under “Permissions”):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadForGetBucketObjects",
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject"],
"Resource": ["arn:aws:s3:::s.country/*"]
}
]
}
Apply this policy to your bucket:
aws s3api put-bucket-policy --bucket example.com --policy file://bucketpolicy.json
Now, upload a simple redirect rule to your S3 bucket that redirects to https://example.com/redirect
with an index.html
in your local repository:
aws s3 cp index.html s3://stse.one/index.html --acl public-read --website-redirect https://harmony.one/2023
This will enable the default page of your bucket to lead to index.html
which redirects to https://example.com/redirect
.
Set up Amazon CloudFront Distribution
Create a new CloudFront distribution. Use the S3 bucket you created as the origin.
Configure the distribution to use the SSL certificate you created in ACM.
Set the Viewer Protocol Policy to "Redirect HTTP to HTTPS".
Note down the CloudFront distribution ID.
This process is complex to handle via AWS CLI, and typically done through the AWS Management Console for ease of use and due to the number of configuration options.
Link CloudFront to Route 53
In Route 53, create a new record set in your hosted zone.
aws route53 change-resource-record-sets --hosted-zone-id "/hostedzone/YOUR_HOSTED_ZONE_ID" --change-batch file://dnschange.json
In the above command, you need to replace YOUR_HOSTED_ZONE_ID
with your Route 53 hosted zone ID. dnschange.json
is a JSON file that specifies the changes to be made to the record sets. This file might look something like this:
{
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "example.com.",
"Type": "A",
"AliasTarget":{
"HostedZoneId": "Z2FDTNDATAQYW2",
"DNSName": "d12345abcdef8.cloudfront.net",
"EvaluateTargetHealth": false
}
}
}
]
}
In this JSON, replace Z2FDTNDATAQYW2
with the zone ID of your CloudFront distribution (found in the CloudFront console) and d12345abcdef8.cloudfront.net
with your CloudFront distribution domain name.
Alternatively, using the AWS Management Console:
- In Route 53, create a new record set in your hosted zone.
- Set the type to "A – IPv4 address" and the Alias to "Yes".
- Set the Alias Target to the CloudFront distribution you created (after “Distribution Status” change from “InProgress” to “Deployed” in Cloudfront).
Create Redirects
Use the AWS CLI to create redirect rules. The command to use is:
aws s3 cp object s3://example.com/$1 --acl public-read --website-redirect $2
where $1
is the path you want to redirect and $2
is the URL to redirect to. You need to have a object
in your local repository (note that this can be an empty file as the contents will be ignored; an object is required to be uploaded).
With this, you can have example.com/food
redirected to your desired destination.
*** Remember to replace example.com with your own domain and make necessary adjustments in the path or redirect URL as per your requirements.
*** Remember to set the appropriate AWS credentials to your environment before proceeding. Validity of the credentials can be checked through simple commands (i.e. aws s3 ls
).
h.country
Setup
The above instruction is for hosting the end to end webserver in AWS. The current setup for h.country
is different than the one explained above.
It looks as follows:
www.h.country
is a webserver hosted in Aaron’s GCPh.country
is a S3 bucket hosted under Harmony’s account
The following redirects have been configured:
- h.country vanity to www.h.country subpage:
h.country/{path}
→www.h.country/page-{desired subpage}
- www.h.country vanity to www.h.country subpage:
www.h.country/{path}
→h.country/{path}
→www.h.country/page-{desired subpage}
- h.country / www.h.country vanity to external website:
h.country/{path}
→{desired external website}
ORwww.h.country/{path}
→h.country/{path}
→{desired external website}
- h.country / www.h.country vanity to nonexisting www.h.country subpage:
h.country/{path}
→www.h.country/page-{nonexisting subpage}
→www.h.country
ORwww.h.country/{path}
→h.country/{path}
→www.h.country/page-{nonexisting subpage}
→www.h.country
All subpages under www.h.country
have “page-” prepended to their paths.
Thus, unless the path of www.h.country has “page-” prepend, the redirect will lead to h.country/{page}
. If the resource {path}
exists under h.country
S3 bucket (s3://h.country/{path}
), then a redirect will happen to the website-redirect
that has been set to the resource. Note that if the redirect of the S3 resouurce is to a www.h.country
but does NOT have “page-” prepend, it will redirect back to h.country
, which will most likely not have the path object and then ultimately onto h.country
.
This applies for all the redirects in any other S3 buckets. For an example, if we want to redirect harmony.one/q3
to https://www.h.country/page-q3-make-something-people-want-b-b-4de738ae0a5948e19cd308dd49b699b2:
aws s3 cp q3 s3://harmony.one/q3 --acl public-read --website-redirect https://www.h.country/page-q3-make-something-people-want-b-b-4de738ae0a5948e19cd308dd49b699b2
If h.country
S3 bucket already has an object that redirects to https://www.h.country/page-q3-make-something-people-want-b-b-4de738ae0a5948e19cd308dd49b699b2, let’s say h.country/q3
:
aws s3 cp q3 s3://harmony.one/q3 --acl public-read --website-redirect h.country/q3
Redirect Update Script
Due to this new setup, all preexisting redirects to www.h.country/{path} needed a “page-” prepend. The following scripts to the following:
#!/bin/bash
# Set the appropriate variables
bucket_name=harmony.one
prefix=page-
redirect_url=https://www.h.country/
# File to store the update details
output_file="update_details.txt"
# Emoji regex pattern (limited)
emoji_pattern=".*[\xF0-\xF4].*"
# Get a list of all objects in the bucket
objects=$(aws s3 ls "s3://$bucket_name" --recursive | awk '{print $4}')
# Iterate through each object
for object_key in $objects; do
# Check if object_key contains an emoji
if [[ ! $object_key =~ $emoji_pattern ]]; then
# Check the file type
file_type=$(aws s3api head-object --bucket "$bucket_name" --key "$object_key" --query 'ContentType' --output text)
if [[ $file_type == "binary/octet-stream" ]]; then
# Get the existing redirect configuration for the object
redirect_config=$(aws s3api head-object --bucket "$bucket_name" --key "$object_key" --query 'WebsiteRedirectLocation' --output text)
# Check if the object has a website redirect to the specified URL
if [[ "$redirect_config" != "None" ]] && [[ "$redirect_config" == "$redirect_url"* ]]; then
echo "Updating redirect configuration for object: $object_key"
# Extract the path from the existing redirect URL
path=${redirect_config#"$redirect_url"}
# Check if the path already contains the prefix
if [[ "$path" != "$prefix"* ]]; then
# Add the prefix to the path
new_path="$prefix$path"
# Create the updated redirect URL
updated_redirect_url="$redirect_url$new_path"
# Update the redirect configuration for the object
aws s3 cp "s3://$bucket_name/$object_key" "s3://$bucket_name/$object_key" --website-redirect "$updated_redirect_url" --acl public-read
# Append the details to the output file
echo "$object_key, $redirect_config, $updated_redirect_url" >> $output_file
else
echo "Path already contains the prefix. Skipping update for object: $object_key"
fi
fi
fi
fi
done
*** This script is specific to harmony.one
bucket. Please change the bucket_name
to the desired S3 bucket.