5

I have following configuration:

Cloudfront - ELB - AutoScalingGroup - EC2s

  • Cloudfront serves file-[hash].js files (with chunkhash in their names) from custom origin (ELB).
  • EC2s serve the file-[hash].js files for Cloudfront plus dynamically generated index.html file that points to appropriate .js file at Cloudfront.
  • ELB has connection draining enabled.

Everything works fine until a Cloudformation deployment with a changed asset is triggered (let's say from file-1.js to file-2.js) - when the new version is being switched on, there is a short time window when browser gets the new index.html file pointing to file-2.js, but when it tries to download file-2.js it gets 404 from Cloudfront, thus showing an error to the user.

I understand this is because how blue/green deployment works - i.e. there is a time when two versions of the application works simultaneously and ELB can redirect one request to the new version (request for index.html from the browser) and second one to the old version (request for file-2.js from Cloudfront).

Cloudfront docs say that you should "host and serve the same content on all servers.", but how can I achieve that during the deployment? Is it possible to enforce that only single version of application is accessible through ELB at any given time, so that Cloudfront never gets 404 for the new assets?

If not, are there any other options to solve this, apart from switching from custom origin to S3? (would like to avoid it due to deployment / maintenance complexity)

Note switching from update policy AutoScalingRollingUpdate to AutoScalingReplacingUpdate did not help:

 asg:
    Type: AWS::AutoScaling::AutoScalingGroup
    CreationPolicy:
      ResourceSignal:
        Count:
          Ref: 2
        Timeout: PT10M
    UpdatePolicy:
      AutoScalingReplacingUpdate:
        WillReplace: true
3
  • I tried solving this with ELB session affinity, but it was too complex to propagate this affinity through CloudFront, which will cache the responses with an AWSELB cookie but not serve the same cookie to further hits (because ELBs specify Cache-Control: no-cache=set-cookie) May 10, 2017 at 16:32
  • Did you ever get anywhere with this?
    – Andy
    May 18, 2020 at 14:16
  • @Andy, no, I'm now always serving static content from S3.
    – mgr32
    May 19, 2020 at 17:35

1 Answer 1

1

I think the solution to this is to keep the static .js files in S3, and maintain previous versions alongside new ones during publish of new applications.

CloudFront will serve the static content from S3, and the dynamic content from EC2.

Publish the static content to S3 first, then start transition.

In this case, the dynamically generated index page would refer to one S3 bucket in the old version, and another in the new. Since both resources always resolve in S3 there will be no 404.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .