Search code examples
amazon-web-servicesamazon-s3amazon-cloudfrontamazon-route53

301 redirect loop when setting up static website with S3, Cloudfront, SSL


I'm attempting to host a static website in AWS for example.com and www.example.com using HTTPS. My current setup properly redirects to to example.com but hits Chrome with a zillion 301 redirects.

The most promising info was this tutorial: Cloudfront redirect www to naked domain with ssl

and this stackoverflow answer: Cloudfront redirect www to naked domain with ssl

I have two S3 buckets. In the AWS console for S3, www.example.com is set to redirect to example.com via https, and example.com is set to host a static website.

I have two Cloudfront distributions, each using an SSL certificate generated using ACM from the us-east-1 region. Origin Domain Name was set by copy / pasting the corresponding S3 endpoint URL rather than using dropdown autopopulate. Alternate Domain Name is set to the matching domain www.example.com or example.com for each distribution.

In Route53, I have two A records, one for each domain. Both are able to see their corresponding Cloudfront distributions populate the dropdown in the Alias menu, and have been selected.

The 301 errors seem to come from cloudfront even in the case where I access the S3 endpoints directly using the long form urls (http response in Chrome devtools has a value of X-Cache: Redirect from cloudfront).

The website is nothing more than an index.html with some text. No javascript in play.

Any help is greatly appreciated. Burning days on this..


Solution

  • The way I have seen this be solved before is the following:

    • Have a CloudFront Distribution for the apex (example.com)
    • Have a CloudFront Distribution for the www subdomain
    • Remove any 301 redirecting done in application or from any distribution
    • Add a Lambda@Edge function to perform a 302 redirect on the CloudFront distribution for the www domain only.

    The redirect function would look like this

    def lambda_handler(event, context):
     
         # Generate HTTP redirect response with 302 status code and Location header.
         uri = request = event['Records'][0]['cf']['request']['uri']
        
         response = {
             'status': '302',
             'statusDescription': 'Found',
             'headers': {
                 'location': [{
                     'key': 'Location',
                     'value': 'https://example.com/' + uri
                 }]
             }
         }
         
         return response
    

    The likely reason you're seeing this is that example.com is also redirecting to itself.

    Also test with a 302 not a 301. 301 is a permanent redirect and can cause problems when attempting to rollback any changes for browsers who have already visited this URL.