Static stite generators are a great, simple way to manage simple websites for the technically savy. S3 is a great way to host static content on the web.

Prerequisites

  1. An AWS account
  2. A static website

I’m not going to cover creating a website with a static site generator, jekyll and hugo are both great options.

Configure AWS

  1. Create and configure the bucket to host the website
  2. Create IAM policy to access bucket
  3. Attach the policy to a group and your user to the group

Create and configure the bucket to host the website

Logon to the AWS Console and head over to the S3 service and create a bucket in your region of choice. Once the bucket has been created, select it and go to the bucket’s properties. Go to the permissions and edit bucket policy on the bucket with the following:

{
	"Version": "2016-02-10",
	"Statement": [
		{
			"Sid": "PublicReadGetObject",
			"Effect": "Allow",
			"Principal": "*",
			"Action": "s3:GetObject",
			"Resource": "arn:aws:s3:::bucket_name/*"
		}
	]
}

Next go to the Static Website Hosting under properties as well and enable it.

Create IAM policy to access bucket

Next we need to create an IAM policy to progamatically push the site to S3. Let’s head over to the IAM service and select Policies on the left hand menu and then Create Policy. Select Create Your Own:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket"],
      "Resource": ["arn:aws:s3:::bucket_name"]
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject"
      ],
      "Resource": ["arn:aws:s3:::bucket_name/*"]
    }
  ]
}

Attach the policy to a group and your user to the group

Now you can create a group to attach this policy to and ensure you user is in that group. Or you can add the policy to an existing group and ensure your user is part of that group.

Configure s3cmd

Download and install s3cmd if you’re on Linux you should be able to install it via your package manager.

$ sudo pacman -S s3cmd

Then head over to AWS and navigate to your IAM user. Select Security Credentials and Create Access Key then download those credentials. Now that we have AWS credentials let’s configure s3cmd:

$ s3cmd --configure

Enter the access key and secret key you’ve just downloaded and provide the password for your encryption key (~/.ssh/id_rsa).

Okay let’s create a quick bash script to deploy our site to S3, add the following to deploy.sh:

#! /bin/bash

cd public
s3cmd put --recursive . s3://bucket_name

I know rather small and simple but I’m lazy and don’t want to have to remember all the specific’s. Anyway I’m of the gemeral opinion that’s how all bash scripts should be, small and simple, otherwise you should be using a more robust langauge to express your instruntions.

Finally we can push our static site to S3:

$ sh deploy.sh

Configure Cloudflare

We’re going to use Cloudflare as our CDN because it’s free, fast and featureful. Go sign up for an account and/or add your website to the account.

DNS

Go to who ever owns your domain and point them to Cloudflares DNS servers, which you can find under the DNS option in the cloudflare management console. While you’re there add a DNS CNAME record to point to the URL of the S3 bucket, which you can find under the static website hosting options under the buckets properties.

SSL

I want to give my site a little SSL love, to do that I’m first of all going to enable full SSL option under the crypto section in the cloudflare management console. This will work because S3 static website hosting supports SSL out the box, so cloudflare should just be able to forward all the traffic over https to the bucket.

Finally let’s force all our traffic over SSL by adding a page rule, head over to the page rule section of the cloudflare management console and add a rule by entering the url and selecting Always use https.

Conclusion

BOOM! you’ve got a blazing fast static website hosted in the cloud for basically nothing with zero server admin.

Just write and push.