Amazon Web Services offers CloudFront, and the ability to serve assets across CloudFront via HTTPS. As we move into the near term future of security on the internet, you should be doing HTTPS-enabled devops and development where possible. At least until someone simplifies this awful, complicated mess of protocols and practices: I deal with SSL certificates all the time and I still don't know most of the commands by heart. And everywhere you look online, you'll see tons of evidence that I'm not alone. For example, the entire first page of Google results for generating private keys with openssl will almost ubiquitously create the keys using the -des or -des3 option. Then a paragraph or two later, they go through an entire step describing the process of removing the encryption password on the keys they just generated! If this isn't proof-positive that most people mostly don't know what they're doing, I don't know what is (and we're ignoring of course that this is basically an appeal to popularity by involving the first page of Google search results).

Anyways, I recently moved several of my websites to HTTPS, and therefore wanted to serve my CloudFront assets (jQuery, Bootstrap, Angular, etc) over HTTPS from my own domain (i.e. not using *.cloudfront.net). In order to do this, Amazon requires that you upload your signed certificate to the IAM certificate server. This is the kind of process that can easily consume a couple of hours for no real good reason other than that Amazon's documentation says a whole lot of nothing useful. Seriously, when I see documentation like this, I know the company has gone far too Enterprise for me to ever want to work there. And Amazon's recruiters for some reason just won't leave me alone. Anyways, that's tangential.

What we're trying to accomplish here is pretty simple from an overview perspective: We want to load our CA-signed certificate file to the AWS IAM Certificate server, and then we'll go into CloudFront and assign our HTTPS connections to use that particular certificate. Sounds neat, but worry not, young padawan, it gets convoluted in the implementation.

First, there is no web interface for uploading certificates to the IAM Certificate server. You have no option but to use the aws-cli utility (sudo apt-get install awscli on Ubuntu 14.04-based distros). Get ready for it, the command looks like this: aws iam upload-server-certificate --path /cloudfront/mysuper/ --server-certificate-name MySuperCert --certificate-body file:///home/user/Downloads/mysuper.crt --private-key file://mysuper.key --certificate-chain file://mysuper.chain.pem. It doesn't say in the documentation we're focusing on (though I'm sure somewhere in that ocean of documentation it mentions configuring the utility), but you need to run aws configuration in order to input your IAM User access key and secret. For the purposes of uploading to the IAM Certificate Server, you're also going to want to add the AdministratorAccess User Policy to your user on the AWS Management Console in your browser. Once you're done uploading your certs, it's a good idea to remove this access if you aren't going to be doing this often. So far, we've now had to interact with the web UI and also the CLI to get this job done, and we're not yet finished with the gotchas.

Please take note of the file:// format you MUST specify for each option. You must be in the same directory as the files you're working with if you're not going to specify a full file path instead of a filename. To help you wrap your head around this, I've used both types in the command in the last paragraph. Oh, and Amazon requires your CA chain file to be in a different format than what virtually everyone else uses. Most CA chain files come with the root CA certificate at the top, then your intermediate CA signatory certificates, and then finally your domain's certificate. This is sane and ubiquitous. Amazon wants "a subset" of this collection (i.e. just intermediate and root CA certs), in reverse order. So for example, if you're using Comodo SSL certs, you're going to cat COMODORSADomainValidationSecureServerCA.crt > mysuper.chain.pem and then cat COMODORSAAddTrustCA.crt >> mysuper.chain.pem and finally cat AddTrustExternalCARoot.crt >> mysuper.chain.pem. You're going to be unable to use the certificate unless you specify a --path that starts with /cloudfront/name/ where name is a descriptive name for your user (and don't forget the trailing slash).

And now finally you're ready to run the command in the paragraph above. God and Amazon willing, you'll get a success message in the form of a JSON object called "ServerCertificateMetadata" with several properties, including the ARN of your uploaded cert.

Now all you need to serve your S3/CloudFront assets over HTTPS from your own domain is to head to your CloudFront distributions interface. Then select the distribution which you want to use your newly-uploaded certificate, click Edit on the settings page, and where it says SSL Certificate you should now have the option to select Custom SSL Certificate (stored in AWS IAM) and use the dropdown to select your certificate by name. Make sure you select Only Clients that Support Server Name Indication (SNI) in the section labeled Custom SSL Client Support below, unless you know you need to support non-SNI-capable clients (and have ample coin to spend on the setup, which can get expensive due to dedicated IPs).

Finally, if you're an architect at Amazon, let me plead with you to reduce the drinking-from-a-firehose feel of the documentation for AWS, and to reevaluate any action that requires both the web UI of the Management Console in addition to the AWS CLI utility. For me, when software has a brittle configuration process, I get the impression that it's not very good software. I love AWS and I've been using it for years (and will continue to do so). But there is so much about it that could be improved.