AWS S3 Static Sites

May 18th 16

I realised that fighting with legacy virtual private servers is no longer worth the effort for me. I began moving my static content over to AWS S3.

S3 is straightforward to setup. It means that you are scalable and can enable CDN in a couple of clicks. It is also cheap and you only pay for what you use.

Static Sites

Setup

You first have to create an access key.

  • Settings -> Security Credentials -> Access Keys

Next create a bucket on S3. It makes sense to name it the domain’s url. Then configure the bucket for static hosting under properties:

S3 Static Website Hosting

Once static hosting is enabled you can point to the index.html.

Note that you will also want to create an www bucket which redirects to the main one. This is so you can handle both urls:

//yourdomain.com
and
//www.yourdomain.com

There is a nice reference explaining a more complicated example here

DNS

Once hosted you will need to redirect your domain to the server to the content.

I decided to use Amazon’s Route 53. The full documentation is available here.

In short you:

  • Create Hosted Zone for the Domain yourdomain.com
  • Add Record sets:
    • NS to point to the S3 servers
    • SOA for the main
      //yourdomain.com
    • A IPv4 for the S3 domain
    • CNAME’s for any subdomains that you have
      //subdomain.yourdomain.com

Pipeline

Once we have setup our page we want the build pipeline to be as convenient as possible.

Ideally as part of the build process once completed we should push our new content live.

There is a handy grunt plugin to worry about the S3 API, Grunt AWS S3. To push the

public
directory up to the root of our
BUCKET_NAME

Note we are assuming that the distribution is in a folder named

public
and that the main index.html lives in the root of the bucket. Also that we are using the region
US Standard
grunt.initConfig({

aws_s3: {
            options: {
                accessKeyId: process.env.AWSAccessKeyId,
                secretAccessKey: process.env.AWSSecretKey,
                uploadConcurrency: 5,
                downloadConcurrency: 5
            },
            production: {
                options: {
                    bucket: ‘BUCKET_NAME',
                    differential: true
                },
                files: [{
                    expand: true,
                    cwd: 'public/',
                    src: ['**'],
                    dest: './'
                }]
            }
        }
    });

Meet for Coffee

Next