Skip to main content

Create a redirection site using Amazon S3

Previously I chose to move all my posts from my old blog at litemedia.info to this blog, and shutdown that site. It was mainly because that site was malfunctioning and I wanted to make the content more accessible on mobile.

After I migrated every blog post, I created the following Web.config in order to redirect all the old URLs to the new domain.

<configuration>
  <location path="unit-testing-in-fsharp">
    <system.webServer>
      <httpRedirect enabled="true" destination="http://blog.mikaellundin.name/2013/03/11/unit-testing-in-fsharp.html" httpResponseStatus="Permanent" />
    </system.webServer>
  </location>
  <location path="game-of-life">
    <system.webServer>
      <httpRedirect enabled="true" destination="http://blog.mikaellundin.name/2013/03/12/game-of-life.html" httpResponseStatus="Permanent" />
    </system.webServer>
  </location>
  <location path="about">
    <system.webServer>
      <httpRedirect enabled="true" destination="http://blog.mikaellundin.name/about/" httpResponseStatus="Permanent" />
    </system.webServer>
  </location>
  <system.webServer>
    <httpRedirect enabled="true" destination="http://blog.mikaellundin.name/" httpResponseStatus="Permanent" />
  </system.webServer>
  <!-- .. and about 250 URLs more .. -->
</configuration>

This works great, the Azure website is redirecting all the old URLs to their target URLs in the new website. However I'm now paying $10 a month for a bunch of HTTP 301, and that doesn't really seem worth it. After doing some thinking I made the conclusion that there are much easier solutions for doing 301 redirects rather than using a Web.config in an Azure website.

S3 bucket

You can host a website from an S3 bucket and it is just a fraction of the cost of an Azure website. By serving content with the HTTP header x-amz-website-redirect-location you can individually redirect each old URL to a new URL1.

redirection can also be done from the bucket configuration

Create a new bucket in Amazon S3 and name it exactly like your domain you want to redirect from. Make sure that you set both index and error in the website settings. By redirecting the error page to the new domain, you will be able to have a catch all scenario where all URLs you have not redirected individually will end up at the root of the new webpage.

when you setup the static website do not use specify redirection at this point

You can choose to redirect the whole website at this point, but I would like to customize redirection for individual URLs and redirecting all requests to a target URL is not what I intend to do.

Setup redirection

Instead I want to create a file for each old URL and upload that file with the HTTP header that redirects to the new URL that I specify. I will do this by using the AWS Command Line Interface.

touch asserting-with-exceptions
aws s3 cp asserting-with-exceptions s3://litemedia.info/ --website-redirect //blog.mikaellundin.name/2009/04/21/asserting-with-exceptions.html

First I create an empty file called asserting-with-exceptions which was the URL for this post on my previous site. Then I upload this file with the HTTP header to redirect to the new URL. Luckily I had a quite flat URL hierarchy at litemedia.info.

After making this file public, I can test it by browsing to the bucket URL http://litemedia.info.s3-website-eu-west-1.amazonaws.com/asserting-with-exceptions and verify that I get redirected to http://blog.mikaellundin.name/2009/04/21/asserting-with-exceptions.html.

I don't want to do this manually to all 250 URLs so what I did was transform the XML with the URLs that I had, using the following XSL.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" indent="yes"/>

&lt;xsl:template match=&quot;/&quot;&gt;
  &lt;xsl:apply-templates select=&quot;configuration/location&quot; /&gt;
&lt;/xsl:template&gt;

<xsl:template match="location"> touch <xsl:value-of select="@path" /> aws s3 cp <xsl:value-of select="@path" /> s3://litemedia.info/ --website-redirect <xsl:value-of select="system.webServer/httpRedirect/@destination" /> </xsl:template> </xsl:stylesheet>

And with some minor adjustments turned the data with the URLs into a runnable script.

#!/bin/bash

export AWSACCESSKEYID=LDS4LSK4JLSKGÖSL export AWSSECRETACCESSKEY=iJSKiLSvmksLSK/OPlskvmosoimfsldklse export AWSDEFAULTREGION=eu-west-1

touch index aws s3 cp index s3://litemedia.info/ --website-redirect //blog.mikaellundin.name/ touch error aws s3 cp error s3://litemedia.info/ --website-redirect //blog.mikaellundin.name/ touch asserting-with-exceptions aws s3 cp asserting-with-exceptions s3://litemedia.info/ --website-redirect //blog.mikaellundin.name/2009/04/21/asserting-with-exceptions.html

.. and about 250 more URLs ..

What is interesting here is that I choose to redirect also index and error, meaning I will catch the root address http://litemedia.info and also any unknown URL with error.

Move the domain to Amazon Route 53

After you've verified that the redirection is working with the bucket url2 you're ready to point the domain to that bucket. If the domain is a subdomain then you can just create a CNAME record to the bucket and it will work all magically.

In my case I wanted to point the whole litemedia.info to the newly created S3 bucket, and that is not possible using a CNAME. Instead we need to use an Amazon service called Route 533.

create a hosted zone for your domain

In this zone you shall create an alias that will point to your bucket.

create an alias that will point at your bucket

Now Amazon Route 53 knows that requests coming to litemedia.info should be routed to the bucket. In the last step we need to tell our domain registrar to use the Amazon nameservers.

find the nameservers by inspecting the hosted zone

You find the nameservers by inspecting the hosted zone that you've created.

I have this domain registered with a registrar called Binero and they allow me to change nameservers from their own to Amazon by a form.

I can use the form at my registrar to update nameservers

And after 24 hours the change had gone through and I would get the Amazon nameserver when querying with nslookup.

nslookup returns Amazon as authorative nameserver

When testing it I can now see that every URL on litemedia.info is redirecting to the corresponding URL on blog.mikaellundin.name.

Mission Accomplished!


Footnotes


  1. You can also setup redirect rules if your redirects follow a specific format. This is not applicable in my case, but if it works for you, please see the following url for more info 

  2. My bucket URL is http://litemedia.info.s3-website-eu-west-1.amazonaws.com 

  3. I found this guide to be immensly helpful for setting up Amazon Route 53. 

comments powered by Disqus