Incompatible: Static S3 Website With CloudFront Forwarding All Headers

a small lesson learned in setting up a static web site with S3 and CloudFront

I created a static web site hosted in an S3 bucket named (not the real name) and enabled accessing it as a website. I wanted delivery to be fast to everybody around the world, so I created a CloudFront distribution in front of the S3 bucket.

I wanted S3 to automatically add “index.html” to URLs ending in a slash (CloudFront can’t do this), so I configured the CloudFront distribution to access the S3 bucket as a web site using as the origin server.

Before sending all of the traffic to the new setup, I wanted to test it, so I added to the list of CNAMEs in the CloudFront distribution.

After setting up Route53 so that DNS lookups for would resolve to the new CloudFront endpoint, I loaded it in my browser and got the following error:

When Are Your SSL Certificates Expiring on AWS?

If you uploaded SSL certificates to Amazon Web Services for ELB (Elastic Load Balancing) or CloudFront (CDN), then you will want to keep an eye on the expiration dates and renew the certificates well before to ensure uninterrupted service.

If you uploaded the SSL certificates yourself, then of course at that time you set an official reminder to make sure that you remembered to renew the certificate. Right?

However, if you inherited an AWS account and want to review your company or client’s configuration, then here’s an easy command to get a list of all SSL certificates in IAM, sorted by expiration date.

aws iam list-server-certificates \
  --output text \
  --query 'ServerCertificateMetadataList[*].[Expiration,ServerCertificateName]' \
  | sort

To get more information on an individual certificate, you might use something like:

Using An AWS CloudFormation Stack To Allow "-" Instead Of "+" In Gmail Email Addresses

Launch a CloudFormation template to set up a stack of AWS resources to fill a simple need: Supporting Gmail addresses with “-” instead of “+” separating the user name from the arbitrary tag strings.

The CloudFormation stack launched by the template consists of:

  • ELB (Elastic Load Balancer)
  • Auto Scaling Group
  • EC2 instance(s) running Postfix on Ubuntu set up by a user-data script
  • Security Group allowing ELB to connect to the instances
  • CloudWatch CPU high/low alarms
  • Auto Scaling scale up/down policies.
  • SNS (Simple Notification Service) topic for notification of Auto Scaling events
  • Route53 Record Set

This basic stack structure can be used as a solution for a large number of different needs, but in this example it is set up as an SMTP email relay that filters and translates email addresses for Google Apps for Business customers.

Because it uses Auto Scaling, ELB, and Route53, it is scalable and able to recover from various types of failures.

If you’re in a rush to see code, you can look at the CloudFormation template and the initialization script run from the user-data script.

Now, let’s look a bit more in depth at the problem this is solving and how to set up the solution.

Replacing a CloudFront Distribution to "Invalidate" All Objects

I was chatting with Kevin Boyd (aka Beryllium) on the ##aws Freenode IRC channel about the challenge of invalidating a large number of CloudFront objects (35,000) due to a problem where the cached copies of the objects were out of date and the system had not been designed with versioning in the object path or name.

In addition to the work to perform all of these invalidations (in batches of up to 1,000 in each request with at most 3 request outstanding) there is also the issue of cost. The first thousand CloudFront invalidations are free in a month, but the remainder of the invalidations in this case would cost $170 (at $0.005 for each object).

It occurred to me that one could take advantage of the on-demand nature of AWS by using the following approach: