DEV Community

Cover image for Deploying a Secure Static Site to AWS with S3, Route 53 and CloudFront
Andrew Alba
Andrew Alba

Posted on

Deploying a Secure Static Site to AWS with S3, Route 53 and CloudFront

There probably hasn't been a better time to host static websites than today. As a developer, you can use some excellent free services such as Netlify, Github, and Firebase.

Hosting a static site in the cloud with companies such as AWS, Heroku, and DigitalOcean can be done at a low cost as well.

Being most familiar with AWS, this is the route I have chosen for a client. These instructions will likely be outdated within a year but should offer some guidance for anyone trying to create a static site that takes advantage of the features and services provided by AWS.

AWS

There are several economic reasons for using AWS to host a static site. AWS provides developers with a free tier for many of their services. Bandwidth and storage costs are low because of the large scale of AWS. AWS can help us manage our custom domain with certificate management, hosted zones, and a content delivery network.

My intention is to provide guidance through this process of setting up and hosting an HTTPS-enabled static website using AWS services with a custom domain. I use Namecheap for domain name registrations, but these instructions can be applied with other registrar services.

There are a few assumptions that will be made for this guide.

  1. You have an AWS account or can create an account before starting the guide.
  2. You have a custom domain registered and access to modify nameserver.
  3. You have about thirty minutes to complete this guide.

Here are the four services we will be using with our static website project.

  1. AWS Certificate Manager or ACM. We can generate an SSL certificate for our custom domain name with this service and set up HTTPS for our site.
  2. Simple Storage Service or S3. As the name suggests, we can upload our static content to a bucket, and serve the files to website visitors.
  3. CloudFront. This is the AWS content delivery network. The service distributes static content to nodes around the globe. This service improves the user experience for worldwide traffic. CloudFront will add a small cost to our hosting fees but provide free SSL termination for HTTPS.
  4. Route 53 is the service to manage our DNS records. This service integrates our custom domain from NameCheap to our CloudFront distribution.

Route Traffic From Our Custom Domain to Route53

  1. Log into your AWS account and open the Route 53 dashboard. In the left navigation, select the Hosted Zone link. Once the Hosted Zone page loads, find and click the Create hosted zone button.
  2. Add your Domain name and a description of the hosted zone record. Leave the default type Public hosted zone selected. Add any tags you would like and click the Create hosted zone button. Create hosted zone
  3. Once your hosted zone is created, select the hosted zone and click the View details button.
  4. Expand the Hosted zone details and take note of the name server records. We will need to use these for our custom domain. View hosted zone
  5. Open a new browser tab and use that to log into your custom domain registrar. Navigate to manage the domain nameservers. For Namecheap navigate to a list of our domains and then click the Manage button. Scroll down to the name server section and change the selected name server from Namecheap BasicDNS to Custom DNS. Under the selection, you can now enter the name server records from step 4. Depending on the registrar, the propagation time of these changes can vary. In my experience, the propagation only takes a few minutes, but it can be several hours for some. Custom domain name server

Generating an SSL certificate

  1. Open a new browser tab and navigate to the ACM service. Click on the Request a certificate button. If viewing the certificate list, click on the Request button.
  2. Under Certificate Type, verify the default Request a public certificate is selected and click the Next button. Request certificate
  3. Add all fully qualified names you plan to use in the Domain section. Keep the default selected DNS validation under the Select validation method. Add any tags (optional) and then click the Request button. Request public certificate

Generation of the certificates will take some time. Once the certificate generates, click on the Certificate ID link to view the certificate. Scroll to the Domains section and take note of the CNAME records. These records will need to be added to the Route 53 hosted zone.
Certificate domain record

Connect Certificates to Hosted Zone

  1. Open the Route 53 hosted zone tab and click on the domain name link to access the records. Scroll down to the Records section and click on the Create record button.
  2. If there is a subdomain record, add that prefix to the Record name. If this is the root domain, leave the field empty. Change Record Type to CNAME. Paste the CNAME value from the certificate record into the Value field. Create zone record
  3. If you have more than one record, click the Add another record button and repeat the step 2 instructions for each record. Once completed, click the Create records button.

Note: We will need to confirm that the certificate has been associated with the hosted records later.

Create an S3 bucket for Static Hosting

  1. Navigate to AWS S3 and click on the Create bucket button.
  2. S3 buckets are global, so you will need to use a unique bucket name. Use your domain name as your Bucket Name. Scroll down and uncheck the Block all public access box under the Block Public Access settings for this bucket section. Scroll to the bottom and select the Create bucket button. S3 bucket create
  3. After the bucket has been created, navigate to the Permissions tab of the bucket and scroll down to the Bucket policy section. Click the Edit button and create a bucket policy to allow public read access to the bucket.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "MySiteGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::example.com/*"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode
  1. Within the bucket select the Properties tab. Scroll down to the Static web hosting section (at the bottom of the page) and click the Edit button.
  2. Select Enable under Static website hosting and Host a static website under Hosting type. Add the static sites Index document (index.html for most) and then click the Save changes button. S3 edit static website
  3. After saving, we should have a URL for the static website provided by S3 (example: http://example.com.s3-website-us-east-1.amazonaws.com). Take note or copy this URL as we will need this to create our CloudFront distribution.
  4. Upload all of your static website files to the S3 bucket. You should be able to verify your site using the link provided in step 5.

Create CloudFront Distribution

Before we start this process, we will want to make sure our SSL certificate has been successfully connected to the hosted zone. Navigate back to the ACM and wait/refresh until the Status shows success.
Issued status

  1. Go to the CloudFront dashboard and click the Create Distribution button.
  2. In the Origin domain field paste in the S3 static website URL from step 5 of creating an S3 bucket. The Name section should populate with the bucket name (example: example.s3-website-us-east-1.amazonaws.com).
  3. Scroll down to Default cache behavior section and select Redirect HTTP to HTTPS under Viewer protocol policy.
  4. Scroll to Settings and be sure to select the price class that is best for your website. If your static hosted site is intended for use in the US only, select Use only North America and Europe for example.
  5. Click the Add item button under the Alternate domain name (CNAME) heading and add each one of your domains. CloudFront settings
  6. Within the selector for Custom SSL certificate, choose the SSL certificate for our custom domain.
  7. Scroll to the bottom and click the Create distribution button.

The CloudFront distribution will take several minutes to generate. Once the distribution is completed, you should be able to access your website using the secure custom domain.

After making updates to your site and uploading the changes to your S3 bucket, you will want to look at creating an invalidation with the CloudFront distribution.

Some Pro Tips for AWS

Within your AWS account, make sure you view your billing dashboard. Within the billing dashboard, you can create a budget. Be sure to use this and create a budget that is acceptable for your use. This can save you from spending more money than you expect in a monthly billing period.

Within CloudWatch, set up a billing alarm for your AWS spending. This can alert you of any unexpected services that you may have left running.

Take advantage of AWS SDK written in your preferred development language for automating deployments and creating invalidations for your CloudFront distributions.

Conclusion

While the tutorial was not as detailed as I initially intended, it is my hope that the tutorial is enough to make your static website public to users. Please take some time to implement the pro tips above and spend some time learning more about the four AWS services we have discussed.

If you have found this tutorial useful and would like to connect, follow me on twitter.

Best of luck and cheers!

Cover image by Caspar Camille Rubin

Top comments (0)