Nuxt.js & AWS: Zero Downtime Deployment
The Problem
I have been using Nuxt.js with AWS ECS, ELB & CloudFront for the past few months. Occasionally I come across this error: Loading chunk _ failed.
ELB rolling deployment routes traffic via a round-robin which splits up into different target groups. The first request that gets routed to a target group requires all the remaining traffic to get routed to the same target group.
Using green/blue deployment won’t solve it either, there is still a short window where the target group switches.
The Solution
I searched for a variety of solution. Most of them will address the problem one way or another but none of them utilises the AWS stack to solve the problem. I don’t mind incurring a little more cost that can potentially save much more in DevOps.
My Considerations
- Utilise AWS Stack (ECS, ELB, CloudFront)
- As little DevOps as possible (Utilise Managed Services)
- Must use Rolling Deployment (slowly migrate users instead of blue-green)
Existing Architecture
Existing architecture routes the traffic from Route 53 to CDN to ALB then to multiple target groups in ECS. ALB to ECS is where the error surfaced.
Proposed Architecture
The new architecture split the traffic at the CloudFront layer into 2 paths. ALB will take care of routing all API services and non-cached objects. S3 will receive all compiled assets (JS/images/manifest).
On deployment, ECS will generate the assets and push /_nuxt and other versioned content into S3. ECS will then proceed to start the website and a health check will be up subsequently. (ELB will not route the traffic to ECS before a healthy health check.)
Whichever target group ELB hits, it will be able to complete the request as all and every possible chunk are now inside S3.
With this deployment strategy, a user that doesn’t refresh their browser even after the deployment is taken offline will still have access to the required chunks. Furthermore, I can also route some decoupled traffic to Lambda@Edge if I need to. (e.g. Generating 3rd party API token or internal authentication.)
Why?
I needed a zero-downtime deployment strategy that is scalable and works well with the AWS stack.
Nuxt.js has its built-in caching ability for assets. One of the advantages of using this method is the ability to cache additional files that are not inside /assets folder and have them delivered from a CDN.