301 Redirects using AWS S3 with Static Hosting and an empty Bucket

S3 buckets allow you to host static content with a pay-per-get model. No monthly fees and no servers – so I considered how I could use this to redirect a limited number of URLs from an old website to a new site.

It couldn’t be a straight forward as the URLs aren’t the same (so using a CNAME, domain forward, or the S3 Redirect requests options were out), but I wanted to preserve the links, and was previously using a .htaccess file to do this. Enter static hosting, on an empty bucket.

We’re setting up the example with “my-redirect-test”

To make this work, I have to at least specify an index document – you can’t save without this – but we’ll be relying on the Redirection rules to apply our logic. I used null as my index document, as this definitely didn’t exist on the source site.

The mapping of your domain to this s3 bucket is covered in this AWS help page (which uses Route53 to assign it).

I’ve got to at least specify the index document, but for the redirects I’ll be using the redirection rules

I want the following logic to be applied:

  • Send https://my-redirect.test.com/aws.html to https://withdave.com/?s=aws
  • Send https://my-redirect.test.com/windows.html to https://withdave.com/?s=windows
  • Send every other request to the new domain with the path intact (e.g.
    https://my-redirect.test.com/azure.html to https://withdave.com/azure.html)

The rules to do this are quite simple, albeit verbose – there’s no logic here other than the stated paths and a catch all. It seems these rules are processed sequentially, so as long as the named redirects are above the catch all (rule with no condition), this works perfectly.

<RoutingRules>
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals>aws.html</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <Protocol>https</Protocol>
      <HostName>withdave.com</HostName>
      <ReplaceKeyPrefixWith>?s=aws</ReplaceKeyPrefixWith>
      <HttpRedirectCode>301</HttpRedirectCode>
    </Redirect>
  </RoutingRule>
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals>windows.html</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <Protocol>https</Protocol>
      <HostName>withdave.com</HostName>
      <ReplaceKeyPrefixWith>?s=windows</ReplaceKeyPrefixWith>
      <HttpRedirectCode>301</HttpRedirectCode>
    </Redirect>
  </RoutingRule>
  <RoutingRule>
    <Redirect>
      <Protocol>https</Protocol>
      <HostName>withdave.com</HostName>
      <HttpRedirectCode>301</HttpRedirectCode>
    </Redirect>
  </RoutingRule>
</RoutingRules>

Note that if you don’t include at least one rule with no condition, users will get a 403 error on any request for another page, as the bucket permissions are set to private.

You could hide the error by using a hosted error page in the bucket though, and by setting that file’s permissions to public.

How much will it cost?

AWS S3 is a pay-as-you-go service, but we’re not storing files here. Instead, users are performing a GET request, which AWS is responding to – so in theory we’ll simply be billed for these GET requests only.

An example request logged in chrome dev tools, with the 301 response and appropriate redirect then applied

If I plug in 1m GET requests into the AWS calculator, the bill comes to a whopping $0.39. Not bad considering there’s no server to maintain.

Using the calculator, 1 million GET requests will cost $0.39 in the us-east-1 region

One Reply to “301 Redirects using AWS S3 with Static Hosting and an empty Bucket”

Comments are closed.