Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirect www to non-www with S3/CloudFront without seperate buckets

I'm hosting a static websites on S3 with CloudFront.

Now, both www.example.com and example.com return the same, but I only want example.com to work, and www.example.com to redirect to example.com.

I know I can create an another bucket that will redirect to the main bucket (example.com), but then I'll have two buckets and two CloudFront distributions for each website and it'll make a mess.

Is there an another way to accomplish that?

like image 803
Theodore Avatar asked Oct 29 '22 09:10

Theodore


2 Answers

Recently AWS introduced Cloudfront Functions. As you can guess it allows you to manipulate http request/response within the cloudfront using custom function code.

In their introductory blog they have covered this specific redirection use case. As per their blog Introducing CloudFront Functions – Run Your Code at the Edge with Low Latency at Any Scale:-

URL rewrites and redirects: Generate a response to redirect requests to a different URL. For example, redirect a non-authenticated user from a restricted page to a login form. URL rewrites can also be used for A/B testing.

I have experimented on this approach. What I did:-

  1. Set up a new cloudfront distribution.
  2. Mapped this distribution to the existing website bucket (doesn't really matter)
  3. Associated a new redirect_www_to_naked function with this distribution.
  4. Mapped this distribution to www subdomain in Route 53

This is how my function looks like:-

enter image description here

And this is my association settings enter image description here

Edit: I wrote a blog about it explaining in detail if you would want to learn more - Redirect WWW to Naked Domain using CloudFront Function

like image 72
Paramvir Singh Karwal Avatar answered Nov 15 '22 06:11

Paramvir Singh Karwal


After spending many hours, searching and trying different solutions, either in Cloudfront or in Route53, the solution that @Paramvir has suggested, has finally helped me figure it out.

I ended up using a Cloudfront function, that looks like this:

function handler(event) {
    var request = event.request;
    console.log(request.headers["host"]);
    if (request.headers["host"] && request.headers["host"].value.startsWith("www")) {
        var response = {
            statusCode: 301,
            statusDescription: 'Moved Permanently',
            headers: {
                'location': { value: 'https://naked_address.com'+event.request.uri }
            }
        };
        return response;
    }
    return request;
}

What it basically does is that it checks for the request address, if it starts with www, then redirects it to naked address. Otherwise it returns the untouched request.

Of course, don't forget to save your function, then publish it. After you do this, you must associate it to your distribution.

like image 44
Wilhelm Sorban Avatar answered Nov 15 '22 05:11

Wilhelm Sorban