Using HTTPS with Amazon S3 and Your Domain

Please note that this post is over a year old and may contain outdated information.
One of the cool things about Amazon S3 (and most other cloud storage services) is that you can map your own domain or subdomain to your bucket using a CNAME, so it looks like resources are being served by your website. The downside is it doesn't work with HTTPS.

For example: Say your main website is www.mywebsite.com and you have mapped your subdomain i.mywebsite.com to your Amazon S3 bucket named "i.mywebsite.com". You can now make calls to resources in your bucket like this:

But if you try to do it with HTTPS, it will not respond:

You can access your bucket directly using HTTPS and it works though:

The reason for this is that Amazon's hosts have valid SSL certificates, while your i.mywebsite.com subdomain does not.

Getting an SSL Certificate and CloudFront

Amazon offers free SSL certificates using the AWS Certificate Manager, but there's no way to assign one to an S3 bucket. You can only assign SSL certificates to an Amazon Elastic Load Balancer or CloudFront distribution.

The solution then is to put your S3 bucket behind a CloudFront distribution, assign the SSL certificate to the CloudFront distribution, and map your domain to your CloudFront distribution URL using a CNAME. It sounds complicated, but setup is pretty easy.

Note About Pricing
Pricing for bandwidth and requests between S3 and CloudFront is similar, though CloudFront can get more expensive if you have a lot of users outside of North America and Europe. You can view S3 pricing and CloudFront pricing to compare them. If you're worried about pricing to remote regions, you can set the "Price Class" to only use US, Canada, and Europe. Or you could also run it all through CloudFlare, which will offload a lot of bandwidth and requests.

Step 1: Get Your Domain ready
You need to be able to receive email at the domain you plan to create an SSL certificate for, so Amazon can verify your domain ownership.

Example: If you plan to create an SSL cert for "i.mywebsite.com", you must be able to receive email at one of any of these addresses:


As well as the email address in your WHOIS lookup for the domain. If you're using WHOIS privacy, that won't be too useful though, so you'll have to make sure you have a valid email at one of the above addresses.

Step 2: Create SSL Certificate
Navigate to Certificate Manager in your AWS console and click "Request a Certificate". Type in the domain/subdomain you'll be using. Hit "Review and request", then "Confirm and request" on the next page. Amazon will send you an email. Go check it and confirm ownership following its directions.

Step 3: Create CloudFront Distribution
Navigate to CloudFront in your AWS console and click "Create Distribution". Click "Get Started" under the Web option (not the RTMP). You'll arrive on the Create Distribution page. Here you need to change three things:

  1. Click inside the input field for "Origin Domain Name". A list of your Amazon S3 buckets should pop up. Select the S3 bucket you want to use.
  2. Scroll to the "Alternate Domain Names (CNAMEs)" field and enter your domain/subdomain you're using (example: i.mywebsite.com).
  3. Scroll down to SSL Certificate and change the option to "Custom SSL Certificate", then select the certificate you just created in the drop-down list. Scroll the rest of the way down and click "Create Distribution".

Step 4: Change Domain CNAME
Your CloudFront "Domain Name" is what you use to access the S3 bucket behind CloudFront. It will look like this:

You can find the CloudFront Domain Name on either your CloudFront dashboard, or after clicking into one of your distributions. Once you have it, change the CNAME for your i.mywebsite record to it. Be sure to wait until your CloudFront distribution's State is "Enabled" though. It will sit as "In Progress" for a few minutes after your create it before it will work.

Once all done, all of these links will point to the same resource in your S3 bucket, and HTTPS will work as intended:

Share This Post
Facebook Twitter

Comments (4)

Terje Dahl   Dec 13, 2017
Very nice. Worked well. One sticking point: SSL Certificate, see: https://stackoverflow.com/questions/28609262/unable-to-select-custom-ssl-certificate-stored-in-aws-iam#28735773 For me, that simply meant using this URL for creating the certificate: https://console.aws.amazon.com/acm/home?region=us-east-1#/wizard/ It then appeared almost immediately. PS. Keep in mind that CloudFont is a web-caching system. That means that you won't see changes to content for a while unless you either adjust the TTL-times under Behavior/Default Cache Behavior, or you do invalidations of files or folders - either manually under Invalidations, or by CLI (from a deploy-script) as part of the deploy. Ex.: aws cloudfront create-invalidation --distribution-id XXX --paths /x/y /z/* /etc.
Kevin Chandler   Jun 07, 2017
Great post! I'll add that you may need to set the "Default Root Object" on your CloudFront Distribution if you'd like the root url to render, say, index.html
William Strachan   Mar 14, 2017
This is a solid write up. Thanks for sharing! Yakir, I'm sure you've figured it out by now, but basically you need to create a CNAME or an A record ALIAS in Route53 that points to your new distribution's Domain Name (i.e. the ***.cloudfront.net thingy).
Yakir Gagnon   Feb 18, 2017
Great post, but I'm really strugling with one sentence in these instructons: "Once you have it, change the CNAME for your i.mywebsite record to it." I managed to follow everyhting up to that point, but not sure how exactly and which CNAME I shoudl change..? In Route 53, in the hosted zone for my website, should I create a new record set, for the ***.cloudfront.net thingy..? Would really appreciate any additional details or help!
Share This Post
Facebook Twitter
H3XED © Nick Vogt   RSS   Policies   Facebook   Twitter   Google+