84

Forgive me if this has been asked before, there are a number of resources that touch on this, but nothing seems to fit for my specific (https) use-case.

I'm trying to redirect https://www.example.com to https://example.com. Likewise, this should work for http://www.example.com to https://example.com.

I have set up a cloudfront distribution with the origin of an s3 bucket, redirect http to https, added the cname example.com and added my domain certificate (which works for the www subdomain as well as the naked domain).

I have also set up a separate distribution, with a cname for www.example.com, added the certificate and set the origin to a separate s3 bucket that in (static website hosting) redirects all requests to https://example.com.

Redirection works as expected for http://example.com to https://example.com, however http(s)://www.example.com to https://example.com does not.

In route 53 I have the root domain aliased to the first cloudfront distribution and www aliased to the second.

Kerem Baydoğan
  • 10,475
  • 1
  • 43
  • 50
Marc Greenstock
  • 11,278
  • 4
  • 30
  • 54
  • Please see my answer here, which should be pretty helpful: http://stackoverflow.com/questions/36265027/how-to-forward-non-www-to-www-with-aws-amazon-cloud-front-behind-https-cloud-fro/41899321#41899321 – Marcel Gruber Jan 27 '17 at 17:18
  • 7
    Rather than close this question, could we move it to Server Fault? I'd like to add an answer. – 2540625 Feb 23 '18 at 21:17
  • +1 for @jtheletter's proposal. Just for the record, I wrote an [in-depth tutorial](https://paulrberg.com/post/2018/12/27/static-website-aws/) on how to set up a static website with S3, CloudFront and Route53. It describes a basic AWS infrastructure for properly handling a www subdomain. – Paul Razvan Berg Dec 27 '18 at 17:10

2 Answers2

129

To host website on AWS so that:

https://www.example.com, http://www.example.com and http://example.com all redirect to https://example.com

you need to:

  1. Create two S3 buckets named: example.com and www.example.com.

  2. Turn on the Static Website Hosting on these two buckets.

  3. Configure redirect in bucket www.example.com to: https://example.com. In the bucket properties choose Static Website Hosting => Redirect all requests to another host name. In Target bucket or domain field, enter example.com, in Protocol field, enter https

  4. For these buckets create two CloudFront Distributions. Each of this distributions point to corresponding bucket:

  5. For Origin Domain Name provide bucket urls provided in Static Website Hosting section. The urls should have form (or similar): example.com.s3-website-us-west-1.amazonaws.com

    • On both distribution set HTTP to HTTPS redirect.

    • DO NOT USE URL SUGGESTED BY AMAZON AUTOCOMPLETE!

    • DO NOT SET Default Root Object PROPERTY!

  6. Configure DNS by setting A records for www.example.com and example.com to point to corresponding CloudFront distributions.

Why does it work? CloudFront provides the redirect from HTTP to HTTPS in both cases (with and without www). The bucket for www.example.com provides redirect to example.com. If you didn't have this distribution, the bucket would not be able to redirect request for https://www.example.com. S3 itself does not support HTTPS for static website hosting.

Raymond
  • 1,172
  • 16
  • 20
RKI
  • 1,899
  • 2
  • 15
  • 18
  • 17
    Do not set HTTP to HTTPS redirect on the www->naked CF distribution to avoid an unnecessary redirect. You want http://www.example.com to go directly to https://example.com not https://www.example.com first. – maletor May 08 '17 at 18:22
  • Don't set the A record on 53 for www. Use a CNAME. Use ALIAS for A and AAAA record on root domain. – maletor May 08 '17 at 18:23
  • @maletor Either one works. ALIAS + A records are not just for root domains, they're used for pointing a DNS entry to a CloudFront distribution. – ffxsam Sep 02 '17 at 23:08
  • 7
    It's also worth noting that simply using a CNAME on www.example.com to point to example.com will not redirect. Instead, www.example.com will bring up the same content as example.com which isn't the same. – ffxsam Sep 02 '17 at 23:52
  • 1
    So my solution was to redirect the www.mydomain.com bucket to domain.com and set the protocol to be https. In each of the Cloudfronts (i.e. the one for www.mydomain.com and the one for mydomain.com) I set the CNAME to be, respectively, www.mydomain.com and mydomain.com. Once I had done this, in S3, I was able to select the appropriate Cloudfront as the Alias for A record. As per the above, I did not use the URL suggested by autocomplete - I used the static website hostname - and I did not set the default root property. – Sam Kenny Sep 26 '17 at 01:26
  • @SamKenny when you say "Once I had done this, in S3, I was able to select the appropriate Cloudfront as the Alias for A record" - do you mean Route 53, not S3? Because youcan't set an Alias in S3. – Miriam Schwab Oct 13 '17 at 13:43
  • Thank you @MiriamSchwab! You are absolutely right. I had the number right... – Sam Kenny Oct 16 '17 at 02:50
  • does anyone know WHY this works if in route 53 you set up www as CNAME for naked? I'm mystified. – bryan60 Jul 10 '19 at 20:51
  • Since we are required to not specify the "Default Root Object", what happens when a user goes to, say, `https://example.com`? Will he be shown the "index.html" page content by default? – John Red Dec 30 '19 at 07:24
  • i tried this exactly and am getting a 301 redirect loop. spending hours and hours tutorial after tutorial ... :( – StayCool Jul 04 '20 at 09:38
  • 5
    Why no body explains that you need to install SSL certificate for every redirect you make in order to prevent "not secure" warning from the browser? its basic but people like me "just a developer" doesn't know that. I spent days trying to solve it until I discover this advice... – Philip Enc Aug 01 '20 at 21:33
  • I'm getting the same error. Could you elaborate more on the SSL certificate issue? – Frankster Nov 29 '20 at 23:12
  • @Frankster You need to create SSL certificate for domain *.example.com and in additional addresses provide bare example.com. Then you need to these certificate for both CloudFront distributions for www.example.com bucket and example.com bucket. – RKI Dec 03 '20 at 19:50
  • 1
    70+ lines of CloudFormation to achieve such a simple thing... – tschumann Nov 17 '22 at 02:19
60

I found the solution thanks to this answer: Amazon S3 Redirect and Cloudfront

In short:

Cloudfront does not respect the redirection rules setup in S3 if the origin is just the bucket ID. Instead I had to set the origin to the provided s3 static website host name.

Community
  • 1
  • 1
Marc Greenstock
  • 11,278
  • 4
  • 30
  • 54
  • 8
    Thank you very much for posting your answer. I used it to get HTTPS redirects from naked domains to www, e.g. [https://example.com](https://example.com) -> [https://www.example.com](https://www.example.com). This solution is counterintuitive because the AWS UI autocompletes to the standard S3 hostname (bucketname.s3.amazonaws.com), which you would think would be the correct way to do it, but for this use case, the static website hosting endpoint (e.g. bucketname.s3-website-us-east-1.amazonaws.com) is what you need. – kellen Aug 19 '15 at 05:05
  • 8
    It is also important that your CloudFront distributions do **not** have anything set as the **Default Root Object**, because it will break the redirection in the S3 bucket. – Michał Czapliński Jun 06 '16 at 01:32
  • 1
    Your link points to a question. Which answer to that question did you intend to link? – 2540625 Feb 23 '18 at 20:40
  • @kellen, how do you forward apex to www? That's what I'm trying to do for my HTTPS domain. My canonical URL's include the www. – Costa Michailidis Jun 30 '18 at 04:32
  • 1
    @Costa have a look at the instructions in this answer. Just reverse the domains, since you want apex -> www. The important thing is to use the URL provided in the bucket under the Static Website Hosting section as the CloudFront target, not the autocomplete URL. https://stackoverflow.com/a/42869783/94671 – kellen Jul 03 '18 at 15:52
  • As of 2020 now, I was in same problem yesterday, and I tried a lot including this suggestion. It work for http://www.example.com to https://example.com but not for https://www.example.com So I figure out a new solution. Instead of redirecting in www.example.com S3 Bucket, that bucket hosts index.html that redirects to https://example.com both cloudfront distribution uses separate ssl certificate from ACM. That makes no problem for https://www.example.com and http://www.example.com to redirect to naked domain. Unless it's not that easy. Thanks – Monolord's Knight Apr 08 '20 at 14:41
  • As of 2020, people should be using Lambda@Edge functions for this kind of logic: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-at-the-edge.html – Razvan Grigore Nov 10 '20 at 15:18