Skip to content

Jesses Software Engineering Blog

Aug 27

Jesse

AWS S3 Web Hosting

Amazon’s Simple Storage Service (S3) is a simple, cheap way to store data. It’s not the lowest latency storage option available, but it is a great tool for scalable, durable storage, making it a perfect candidate for hosting a website.

To get a site hosted, first create a bucket and enable Static Web Hosting under the Properties tab. Be sure to define a root document i.e. index.html. While the naming conventions for S3 are fairly loose, I suggest sticking with DSN safe characters (no periods) in order to take advantage of some of the newer features like Transfer Acceleration. The site will not load from S3 until the correct permissions are set via the Bucket Policy under the Permissions tab.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::<bucket-name>/*"
    }
  ]
}

At this point the bucket will be serving the website. NOTE: While S3 can only support static websites, it can still host apps built in ReactJS, AngularJS, etc. which can load dynamic data via AJAX and an API.

If your static website doesn’t change very often, one thing that can be done to help performance is to setup CloudFront, Amazon’s CDN cache, in front of the bucket. To configure CloudFront, set up a web distribution and put the origin as the S3 site domain. For object caching setting, can use the Origin Cache Headers option and define the Cache-Control header on the S3 file via the Bucket Properties, but deploying the website (new files) to S3 will wipe out the custom headers. An alternative option is to set the min, max, and default TTL on the CloudFront distribution itself for the entire bucket.

Amazon also offers a DNS service. A domain for the site can be registered directly with AWS or transferred over from another registrar. To get a domain pointing at CloudFront, setup an A record with an alias pointing to the CloudFront url. A second A record for the www. prefix will be needed as well. In order for CloudFront to render properly from the domain, register the CNAMEs (domain values) with CloudFront.

When pulling up the domain, the S3 bucket index file will be loaded and an inspection in the browser dev tools will show a second page load as X-Cache: Hit from cloudfront.

While bucket deployments can easily be handled via the AWS UI, they can also be run programmatically command line via the AWS cli tool. To run deployments a user with correct permissions will need to be used. A custom user policy can be set as:

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

Notice the difference in the arn values for the bucket and the object actions. While ListBucket and GetObject are not required they can be helpful to see what’s currently in a bucket. After setting up the user and generating the access tokens, the CLI can be configured to use different user profiles. An S3 upload could be:

aws s3 sync build/ s3://<bucket-name> --profile <profile-name>

This will put the entire contents of a project folder into the root of the S3 bucket and can be easily built into build tools. Having a website set up with the combination of CloudFront and S3 allows for unlimited horizontal scaling, guaranteed up-time, and low latency web applications. Another great benefit is you only pay for what you use, so this is a great architecture stack for prototyping and building new products.

Blog Powered By Wordpress