This article describes the installation and configuration of a static website on Amazon Web Services. Includes redirection of HTTP
to HTTPS
, redirection of www
sub-domain to the apex domain, redirects listed in a json
file, updated security headers, basic authentication, custom error page, etc.
Create a zone file for your domain if it doesn't exist. We will refer to the domain name as domain.tld
throughout this document. Make sure to replace all mentions with your actual domain name. You will create A
records later that will link your domain names to a CloudFront distribution.
Don't forget to point your domain's nameservers to AWS. See the NS
record in Route 53 for the nameservers to use with your registrar.
Request a public certificate for your domain. Add the following domain names:
domain.tld
*.domain.tld
Create a new Amazon S3 bucket named domain.tld
. Copy your website files to the S3 bucket. We will not be using the Amazon S3 static website feature. Keep the bucket private. CloudFront will add a bucket policy later for secure access using Origin Access Identity. You can enable server-side encryption (SSE) if you want.
Create a new web distribution with the following settings:
- Origin Domain Name: select
domain.tld.s3.amazonaws.com
from list - Origin ID:
S3-domain.tld
- Restrict Bucket Access:
Yes
- Origin Access Identity:
Create a New Identity
- Comment:
OAI-domain.tld
- Grant Read Permissions on Bucket:
Yes, Update Bucket Policy
- Viewer Protocol Policy:
Redirect HTTP to HTTPS
- Compress Objects Automatically:
Yes
- Lambda Function Associations: will be added later through Lambda@Edge
- Alternate Domain Names (CNAMEs):
domain.tld
andwww.domain.tld
- SSL Certificate: select custom SSL certificate for
domain.tld
Leave all other settings with their defaults. Create the distribution.
Create a custom error response with the following settings:
- HTTP Error Code:
403: Forbidden
- Customize Error Response:
Yes
- Response Page Path:
/404.html
(rename for your error page) - HTTP Response Code:
404: Not Found
The reason the selected HTTP error code is 403
is because we are accessing S3 using the REST API which returns a Forbidden
error instead of Not Found
.
Create an IAM Role for executing your Lambda@Edge functions. Name your role cloudfront-lambda@edge-role
. Attach policies AWSLambdaEdgeExecutionRole
and AmazonS3ReadOnlyAccess
. Edit the trust relationship and add this policy. See documentation for more information.
Install a combination of CloudFront Functions and Lambda@Edge Functions in CloudFront Behaviors for each static site as per your needs:
Function | Function Type | Event Type | Path Pattern |
---|---|---|---|
Accept-Language | CloudFront | Viewer Request | / |
Basic Auth | Lambda@Edge | Viewer Request | Default (*) |
Directory Index | Lambda@Edge | Origin Request | Default (*) |
Form | Lambda@Edge | Origin Request | <path>/ |
Redirect Alternate | CloudFront | Viewer Request | Default (*) |
Redirect www to Apex | CloudFront | Viewer Request | Default (*) |
Redirects | Lambda@Edge | Origin Response | Default (*) |
Security Headers | CloudFront | Viewer Response | Default (*) |
You can only use a CloudFront event once for each cache behavior so you may need to use Lambda@Edge functions to get around the limitation. Directory Index could be a CloudFront function but the Viewer Request event type is used for other purposes.
Amazon Route 53 (continued)
Create two new simple records:
domain.tld
- Record name: leave empty
- Route traffic to: select Alias to CloudFront distribution and then your distribution
- Record type:
A
www.domain.tld
- Record name:
www
- Route traffic to: select Alias to CloudFront distribution and then your distribution
- Record type:
A
- Record name:
A few commands to automate the deployment of your static websites.
Copy files to Amazon S3 bucket.
aws s3 sync <folder>/ s3://<domain.tld> --delete
Remove objects from CloudFront edge caches.
aws cloudfront create-invalidation --distribution-id <id> --paths '/*'