Man-months and counting…

There are numerous tutorials out there that instruct one on how to build a static website with AWS and/or terraform. This is not one of them. Instead I‘d like to show you the first way in which Atmos Pro can save you some time.

To do a static website with AWS, one can get away with using just a s3 bucket in website mode. However, as your needs evolve, and you need ssl, redirects, CDN, etc, it becomes necessary to add to this. Typically one could use a proxy or some other ssl endpoint with redirect logic, but since CloudFront CDNs handle a lot of this, it makes sense to just use it and not have to worry about keeping things up and running. Alternative CDNs like CloudFlare are also an option, but there are numerous benefits to limiting the count of providers you depend on, so where possible, we do it all with AWS.

It can also be useful to have your site content hidden from the internet, and only give it access through the CDN. For example, this lets you hide sensitive information behind a paywall, but still have the ease of hosting it that s3 provides. Thus the Atmos Pro recipe sets up the s3 bucket as private, with only the CDN being able to access it.

Given all that, our desired setup looks like this:

This is somewhat complex, and would be a pain to create/maintain/duplicate through the standard tools for working with AWS. However, abstracting it out into a terraform module gives us all the power of code, so we may as well make it easy to do it this way by default. This leads us to the Atmos Pro interface for creating a static website with this behavior:

module "static-website-www" {
source = "../modules/static-website"
  // Boilerplate to enable transparent use across
// multiple environments/accounts
atmos_env = "${var.atmos_env}"
global_name_prefix = "${var.global_name_prefix}"
local_name_prefix = "${var.local_name_prefix}"
  // The name of the component
name = "www"
  // The primary hostname (first) and as many aliases as desired
// Note if you preferred www to be the primary, simply
// reversing the order will do the trick
aliases = ["${var.domain}", "www.${var.domain}"]
  // The route53 zone to add hostnames to
// This is setup by atmos
zone_id = "${module.dns.public_zone_id}"
  // The ssl cert to associate with the hostnames
// This is setup by atmos
certificate_arn = "${module.wildcart-cert.certificate_arn}"
  // Name the bucket containing the static website
site_bucket = "${var.website_bucket}"
  // Access logging to the given bucket
logs_bucket = "${var.logs_bucket}"
  // Makes cleanup easy in dev environments, but difficult in prod
force_destroy_buckets = "${var.force_destroy_buckets}"

You can have as many aliases as you’d like, the first in the list being the target for all the redirects from the others. SSL by default — its free and atmos already set it up, so why not? The use of Route53 Alias records allows it to work with the bare domain as the primary or as a secondary alias.

Note that the CDN handles the https -> https redirect, and the Lambda@Edge handles the secondary_alias -> primary_alias redirect. This is not quite perfect in that a request to http://secondary results in two redirects, first to https://secondary then to https://primary. However, its probably good enough for most usages of aliases. The lambda also handles rewriting the url to access the default_root_object in subdirectories, i.e. requests to /mypermalink get sent to the origin (bucket) as /mypermalink/index.html . This makes it easy to use (with the permalink feature) on a static site generation tool like jekyll. The redirect and deep root object behaviors can be disabled, and the lambda function that handles them is also customizable, all while being tracked in your own repo that is under source control.

Once the AWS resources are in pace, deploying the website is just a matter of copying the files to the s3 bucket and invalidating the CDN cache. For example:

cd website
jekyll build
aws s3 sync --delete ../website/_site/ s3://your-production-www/
aws cloudfront create-invalidation --distribution-id=XXXYYYZZZ123 --paths /

All said, this isn’t a particularly earth shattering recipe. Maybe it would take you a day to do the same manually — then again, and again as you duplicate or maintain it. Maybe a few days to do it in an automated fashion yourself. The value proposition for Atmos Pro is to accumulate enough of these that it saves you enough time to make the purchase compelling.

What would you like me to create for you?