Introduction and Prerequisites

This articles shows how to host your static Website, almost for free.

You need to have an Amazon Web Service (AWS) Account so that you can login to the AWS Management Console.

Create a bucket

In the AWS Management Console, create a new Bucket with the name of the domain you want to host(e.g. www.yourdomain.com).

If you want to use a custom domain name, the bucket name must match the domain or you will run in 404 errors displaying Code: NoSuchBucket. Also make sure, that you use a subdomain and not a top level domain. This is because you will later have to set a CNAME Record of the domain you are hosting. CNAME Records invalidate most other Records, including the MX Record required for Mailing. Thus, if you want you S3 Website to be available through the top level domain and still be able to receive emails, the best way to go is hosting the S3 Website on a subdomain like www.tld.com and redirecting tdl.com to it.

When you have created your bucket, enable the Website feature in the Bucket Properties. Fill in the name of the file you want as landing page in the Index Document field (usually index.html). Now save you settings and head over to the URL displayed as "Endpoint" in the Website Tab of your bucket. Since you haven't allowed visitors access to your files yet, you will get an 403 Forbidden Error. So let's grant everybody access:

In the Permissions Tab of the bucket properties, create/edit the bucket policy and fill it with the following content:


{
    "Version": "2008-10-17",
    "Id": "",
    "Statement": [
        {
            "Sid": "AddPerm",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::robin.wenglewski.de/*"
        }
    ]
}

Replace robin.wenglewski.de with the name of your bucket.

Synchronize Content

The tool s3cmd, which is available for OS X and Linux, can be used to synchronize the local folder containing your website with the S3 bucket. It can easily be installed under OS X with homebrew (brew install s3cmd) or under Debian-based Linux with aptitude install s3cmd. Run s3cmd --configure after the installation to give s3cmd access to your buckets. You will have to insert the access key and the secret key to your AWS account. Both keys can be found under Security Credentials in your AWS Account.

After you are done configuring, you can simply upload you content with s3cmd sync --rr --delete-removed dir/ s3://bucket. Replace dir with the directory containing your website and bucket with your bucket name. The --rr option sets all files to be uploaded as Reduced Redundancy files which is definitely enough if you keep a backup on my local machine anyway. After the upload is complete, you should be able to visit the Endpoint URL displayed in the Website tab of your bucket properties.

Custom Domain Name

Now the Endpoint URL does look quite ugly. To be able to set a custom domain name, you need to be able to access your domains nameserver (or email the guys that manage it). Create a CNAME Record with the name of your subdomain (www) and as value of your Endpoints domain (the url without the http:// and the trailing /).

If you have visited your domain recently, you will not be able to see the result immediately, since the old entry will be cached on your machine. The time to live of DNS-Entries is usually 1 hour. So either wait that long or reset your DNS cache (under OS X: dscacheutil -flushcache). After a while, you should be able to access your page with your custom url.

Cloudfront

Cloudfront is the Content Distribution Network (CDN) of Amazon. It can increase the speed of your website by copying the static files to various servers. When a user visits your site, he is automatically directed to the closest Server.

To configure Cloudfront go to the Cloudfront Tab in the AWS Management Console and create a new distribution. The process is pretty straight forward. Cloudfront generates a new Domain (looking like this: d22uzwgrnmz36x.cloudfront.net) which has to be placed as value in the CNAME Record you have created earlier.

Be aware that by holding copies of your website on various servers, Cloudfront caches your website. So when you upload new content to your S3 bucket, it won't be visible until the cache expires (as far as I know it is set to one day), or you send an invalidation request. Unfortunately, at the time of writing, s3cmd does not support invalidation requests.

Pitfalls

Policy has invalid resource - arn:aws:s3:::bucket/*

This error is caused by not replacing bucket with your buckets name.

Further Reading

  • Camerons Blog - The effect of using Cloudfront as CDN and how to increase performance even further with gziped-content