Blue/Green deployments with CloudFront

amazon-cloudfrontdeployment

I'm looking for a way to do Blue/Green deployments with CloudFront.

Does anyone have a good solution for moving from one CloudFront distribution to another or does everyone really just create their distribution and then never ever touch it again?

My CloudFront distribution consists of one S3 origin for static content (javascript, etc) and a custom origin pointing to an AWS ELB.

No Changes To CloudFront

Under normal circumstances we don't make any changes to our CloudFront distribution at all. We version our static content in the S3 origin by changing the name of the static content files in S3 and do rolling deployments to EC2 instances under the Elastic Load Balancer (ELB). However, there are times when we need to test and make changes to the CloudFront distribution itself or have significant enough changes to our environment that we need to point to a new ELB in a new environment.

Two CloudFront Distributions

The first option I attempted was to have two separate CloudFront Web Distributions, one for my current, or A, environment and one for my new, or B, environment. I attempted to use a Route53 weighted routing policy where I added two records for my www.domain.com Route53 record, one pointing to CloudFront Distribution A with a weight of 1 and the other pointing to CloudFront Distribution B with a weight of 0. The plan would be to change the weights when I want to move from distribution A to distribution B. However, only one CloudFront distribution at a time can have the www.domain.com Alternate Domain Names (CNAMEs) registered or you get the following error:

com.amazonaws.services.cloudfront.model.CNAMEAlreadyExistsException: One or more of the CNAMEs you provided are already associated with a different resource. (Service: AmazonCloudFront; Status Code: 409; Error Code: CNAMEAlreadyExists; Request ID: ef84a5f0-44e7-11e5-9315-0ba167bb108a)

One CloudFront Distribution

The second option is to keep one CloudFront web distribution.
I have S3 and custom origins pointing to both my A and B environments and then I update the CloudFront Cache Behavior to point to the other origin when I want to move from one environment to another. This is extremely messy because these updates take 15-60 minutes, there is no visibility into the progress of the update and depending on the nature of your change you may need to follow that up with a CloudFront Invalidation so you aren't serving cached content from the old environment along with new content.

Thanks for your advice!

Best Answer

Two Cloudfront Distributions

Since AWS allows for overlap between wildcard alternate CNAMEs in the same AWS account, you can switch between two cloudfront distributions in the following manner:

  • Use www.domain.com as Alternate CNAME for Prod distribution 1
  • Use *.domain.com as Alternate CNAME for Prod distribution 2
  • Point your CNAME DNS www.domain.com to distribution 1 or distribution 2. (*.cloudfront.net).
  • Remove the alternate CNAME from the distribution which you don't want to serve the content from anymore.

However, the two different distribution DNSs (*.cloudfront.net) may point to the same edge nodes, which means that the way your content is served is by matching the cloudfront.net CNAME to the Edge nodes serving it and then to match by hostname. In this case, if both your distributions are using the same edge nodes (it can be checked for example with dig) the cut will not be clean.

e.g. If both distributions share one or more edge nodes, distribution 1 with Alt CNAME www.domain.com will take precedence over distribution 2 with the more generic *.domain.com until the CNAME gets removed from the distribution 1 config in all edge nodes. So the version retrieved from one request may be different from the other during the transition period.