You'll probably want to handle the www subdomain and the naked apex differently.
1) http://example.com -> https://www.example.com
The easiest route to handle the naked (apex) domain redirects is to go into Route53 and and setup the apex to use an A alias record to an S3 bucket target. In the S3 bucket you can enable "Redirect all requests to another domain" and redirect to https://www.example.com.
This solution would only work for http requests though and not https since S3 won't terminate SSL for an https request. See #3 for a solution that would work for both http and https.
2) http://www.example.com -> https://www.example.com
You can do same domain www http => https redirects using the X-Forwarded-Proto
HTTP header in your application. It will have a value of either http
or https
. If you receive http
you could redirect to https
.
An apache example would look like this:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule . https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
An nginx example could look like this:
if ($http_x_forwarded_proto != "https") {
rewrite ^(.*)$ https://$server_name$1 permanent;
}
Alternatively, you could front your Elastic Beanstalk app with Cloudfront and implement an http => https redirect there. In "Behavior Settings" you can check the radio button "Redirect HTTP to HTTPS".
3) https://example.com -> https://www.example.com
You will need an SSL cert that has a subject alternate name covering example.com and www.example.com. You could get this for free with AWS Certificate Manager. You can "Add more names" which would allow you to cover *.example.com and example.com in a single certificate. Certificate Manager is fully integrated with Cloudfront so it's a nice option.
Cloudfront Option:
Cloudfront is a pretty good option here -- especially if you use it to front the whole app (apex and www).
Within Cloudfront in "Alternate Domain Names (CNAMEs)" you'd need to add both example.com and www.example.com (separate these with a comma or newline). You'll also specify your digital certificate covering both domains.
Elastic Beanstalk Option:
If you don't want to use Cloudfront you could terminate SSL at the Elastic Load Balancer instead for both apex and www and implement the same !www redirect using your application tier http service (apache, nginx etc.). Just add the SSL cert covering both domains (apex and www subdomain).
Implement the non-www redirect:
With either termination option you'll get a request for https://example.com going back to your origin server on Elastic Beanstalk, however you will need to return a 301 that directs the browser to https://www.example.com at the application tier.
An apache example:
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
An nginx example:
server {
server_name "~^(?!www\.).*" ;
return 301 $scheme://www.$host$request_uri;
}
Route53 Alias Record for Apex:
With either solution you'll need a Route53 A Alias record on the apex to make this work as CNAME records aren't supported for the apex (naked) domain. You'd specify the Elastic Beanstalk target or Cloudfront target.