AWS s3 Redirects

April 29, 2021

Written By: Jerred Hurst

Categories:

Aws,  S3,  Json
AWS s3 Redirects

Recently we were faced with the need to add quite a few redirects to a website that is hosted as a static website on AWS s3.


A little backstory on how we ended up here. Our in-house CMS Bind offers our clients a full CMS experience while publishing their site as as static site to AWS s3. Since the sites are serverless, it adds a wrinkle in the traditional way to create redirects using rewrites from a web server such as Nginx or Apache.


Fortunately, AWS does allow a way for you to add redirects to any s3 bucket that is configured with static website hosting. They offer basic documentation here that got us started, but we did encounter a few nuances along the way.


To begin adding redirects through the s3 UI, you simply click on the bucket, choose the Properties tab, then scroll down to the Static Website Hosting section and click Edit.


Once you are on this page, you can scroll down and find the Redirection Rules editor.


First thing, even though their documentation has examples in XML (which we probably would not have used anyways), their editor only supports JSON.


A basic redirect example is below

[
    {
        "Condition": {
            "KeyPrefixEquals": "golf"
        },
        "Redirect": {
            "HostName": "bbbstx.org",
            "HttpRedirectCode": "301",
            "Protocol": "https",
            "ReplaceKeyPrefixWith": "/news/Golf"
        }
    },
]


In the example above, we are saying that if you visit the https://bbbstx.org/golf that we need to redirect that to https://bbbstx.org/news/Golf


We do this by specifying the original url (key) in the Condition block of the JSON.

This is done by: "KeyPrefixEquals": "golf"


The logic in the Redirect block is pretty obvious, but here it is line by line:


"HostName": "bbbstx.org" ← root domain

"HttpRedirectCode": "301" ← redirect code (not required, but good practice)

"Protocol": "https" ← protocol (http or https)

"ReplaceKeyPrefixWith" ← path you are redirecting to


An annoyance we ran across that we really don't have an explanation for is whether you need the leading slash / in the ReplaceKeyPrefixWith value. In the example above, you will see we do have the proceeding slash in "ReplaceKeyPrefixWith": "/news/Golf", however in another redirect to a remote server, we had to remove this to get it to work.


See the example below:

{
      "Condition": {
          "KeyPrefixEquals": "makeyourmark"
      },
      "Redirect": {
          "HostName": "4agc.com",
          "HttpRedirectCode": "302",
          "Protocol": "https",
          "ReplaceKeyPrefixWith": "donation_pages/f857e304-38f0-4521-a1f9-3e438d9de6b2"
      }
  },


Another unexplained functionality was the order / matching of the keys (urls) for redirects.

There is a good chance there is a reason for this, we could just not find it documented anywhere


In the example below, we have 2 redirects that start with the same word (houston).


First redirect is for /houstonupdates

{
        "Condition": {
            "HttpErrorCodeReturnedEquals": "404",
            "KeyPrefixEquals": "houstonupdates"
        },
        "Redirect": {
            "HostName": "bbbstx.org",
            "HttpRedirectCode": "301",
            "Protocol": "https",
            "ReplaceKeyPrefixWith": "/news/categories/greater-houston-events"
        }
    },


And the next redirect is for /houston

{
        "Condition": {
                        "HttpErrorCodeReturnedEquals": "404",
            "KeyPrefixEquals": "houston"
        },
        "Redirect": {
            "HostName": "bbbstx.org",
            "HttpRedirectCode": "301",
            "Protocol": "https",
            "ReplaceKeyPrefixWith": "/greater-houston"
        }
    },


If the /houston redirect rule proceeds (is above) the /houstonupdates redirect, it will never process the /houstonupdates redirect. It's almost as if it is doing a wildcard search in that the first key that contains houston is the redirect rule that is honored.


Reversing the order and having the more explicit /houstonupdates come before the /houston redirect in the rules works perfectly. 🤷🏼


Even though we did run into a few nuances, with a little trial and error we were still able to add 20+ redirects for our client to a serverless website. Pretty cool!


Next step, add this functionality in Bind and utilize the API so clients can add redirects on their own. 😎