Creating S3 buckets and hosting content

In this example, we're actually going to create two S3 buckets for our site http://www.example.org/. They correspond to the hostnames:

It might be a good time to remind you that S3 bucket names are globally unique. You'll also need to substitute example.org for a domain which you own.
  1. We're going to put all our content in our example.org bucket and tell S3 that requests to www.example.org should be redirected to the other bucket. Here's what the relevant parts of the CloudFormation would look like for creating these buckets (note that we'll be expanding on this example as we proceed through this recipe):
      Resources: 
ApexBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref DomainName
WWWBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub
- www.${Domain}
- Domain: !Ref DomainName
  1. We won't be hardcoding our domain name into the bucket names. Instead we're going to supply our domain as a parameter to the CloudFormation template in order to maximize its reusability, then reference it via !Ref DomainName. To keep this recipe as simple as possible we're going to set up a single page website. In the real world, your website will of course consist of multiple files but the process you need to follow is exactly the same.
  1. Configuring the index document:
    • The index document is the file which S3 will serve by default when someone types your domain name into the address bar in their browser. This precludes the user from having to type the full path to a file, that is, example.org/index.html.
    • Typically, your index document will be called index.html. We'll provide a code snippet for this file towards the end of this chapter.
  1. Configuring the error document:
    • The error document is the file S3 will serve if something goes wrong (missing files, forbidden access, bad requests, and so on). To keep things consistent we're going to call ours error.html. Again, we'll provide a code snippet for this later in the chapter.
  2. Enabling website hosting on your bucket:
    • As mentioned previously, we're going to need to tell S3 that it should serve static website content from our example.org bucket. Often users will perform this configuration through the S3 web console. We're going to do it in CloudFormation however. The CLI also offers a nice one-liner for doing this. You're not going to need to run this command, we're just adding it here for reference:
                aws s3 website s3://example.org/ 
--index-document index.html --error-document error.html
  1. Setting up redirection from the www hostname:
    • When performing this task manually one has little option but to fire up the web console and configure the www.example.org bucket to redirect to the example.org bucket. There's no handy one-line CLI command for this one. Fortunately, it's easy in CloudFormation as you'll soon see in the upcoming CloudFormation snippet.
  1. Configuring permissions:
    • The last bucket setup task is to configure permissions. By default S3 buckets are private and only the bucket owner can see its contents. This is not much use to us in this scenario because we need everyone to be able to see our bucket contents. This is a public website after all.
  1. If we were configuring our bucket manually we would apply a bucket policy which looks something like this:
      { 
"Version":"2012-10-17",
"Statement": [{
"Sid": "Allow Public Access to everything in our bucket",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example.org/*"
}
]
}
  1. Fortunately, in CloudFormation the task is much simpler. Building on the previous example, the Resources section of our CloudFormation template now looks like this:
        ApexBucket: 
Type: AWS::S3::Bucket
Properties:
BucketName:
Ref: DomainName
AccessControl: PublicRead
WebsiteConfiguration:
IndexDocument: index.html
ErrorDocument: error.html
WWWBucket:
Type: AWS::S3::Bucket
Properties:
BucketName:
Fn::Join: [ ., [ www, Ref: DomainName ] ]
AccessControl: BucketOwnerFullControl
WebsiteConfiguration:
RedirectAllRequestsTo:
HostName:
Ref: ApexBucket