Creating URL Redirects with Boto3

Even though most of my back-end development is with C#, I still find Python to be a great tool to work with AWS. I highly recommend Jupyter Notebooks and the AWS Boto3 SDK.

When I first started learning the AWS toolset, I began by using the Management Console. While this is great for some operations, being able to add and maintain resources programmatically makes Dev Ops much more comfortable and more repeatable. Also, using Jupyter notebooks allows you to connect documentation to code, which is excellent when working on a team.

I am assuming you have Anaconda's distribution of Python, and the Boto 3 AWS Python SDK installed.

Creating a bucket is easy.

import boto3
s3 = boto3.resource('s3')
s3.create_bucket(Bucket='redirect-22992299', 
                 CreateBucketConfiguration={ 'LocationConstraint': 'us-east-2'})

The 'Resource' we create here represents the higher level interface to AWS. Here we are creating a new S3 Bucket. Notice that the Bucket name is unique across all users, so you will need to pick a unique identifier here.

Next we will allow the public to read our S3 bucket.

bucket.Acl().put(ACL='public-read') 

We still need an actual redirect, and to create our website redirects. For these, we will add two objects to our newly created S3 bucket. We could write an html redirect in the 'Body' statement below, but AWS provides a WebsiteRedirectionLocation, which we will use so that AWS will redirect before ever sending html to the client.

bucket.put_object(Bucket='redirect-22992299', 
                    Key='index.html', 
                    Body='0',
                    WebsiteRedirectLocation='http://www.designingforthefuture.com')
bucket.put_object(Bucket='redirect-22992299', 
                    Key='error.html', 
                    Body='0',
                    WebsiteRedirectLocation='http://www.designingforthefuture.com')

Even though we allowed the public access to our S3 bucket above, by default the objects created in the bucket will be private. To set public access to our two newly created objects we will set the permissions:

object = s3.Bucket('redirect-22992299').Object('index.html')
object.Acl().put(ACL='public-read')

Now we designate our S3 bucket as a website. To do this, you'll notice we can't use our original s3 object. We create a new object for the lower-level 'client' interface to AWS. These map closer to the AWS services, but are lower-level.

website_configuration = {
    'ErrorDocument': {'Key': 'error.html'},
    'IndexDocument': {'Suffix': 'index.html'},
}
s3client = boto3.client('s3')
s3client.put_bucket_website(
    Bucket='redirect-22992299',
    WebsiteConfiguration=website_configuration
)

Done! With this bucket set, I added a A alias in Route 53 to use the redirect. You can also set these when your S3 object has expired and you want users to be redirected to your current site.

See the complete Jupyter Notebook for full details: https://github.com/rinckd/designingforthefuture-blog/blob/master/notebooks/AWS/01_S3_buckets/01_S3_Buckets.ipynb

Comments