Skip to content

How to design zero-downtime blue/green deployment for Single Page Applications using API Gateway and S3

4 minute read
Content level: Intermediate
0

Guidance to design SPA for blue/green deployments

This article explains an architecture pattern for blue/green deployment of SPAs using Amazon API Gateway stage variables and Amazon S3. Two private S3 buckets hold different application versions, and API Gateway controls which version users see. Switching between versions is a single API call that takes effect in approximately one second — no redeployment or infrastructure changes required.

Architecture Overview

Users → API Gateway (prod/blue/green stages)
              │
              ├── Stage Variable: bucketName
              │
         ┌────┴────┐
         ▼         ▼
    Blue S3     Green S3
    Bucket      Bucket
   (v1)        (v2)

Detailed Design

S3 Buckets — Version Isolation

Each application version is stored in its own private S3 bucket (e.g., react-app-blue-{ACCOUNT_ID} and react-app-green-{ACCOUNT_ID}). Public access is blocked on both buckets — they are only accessible through API Gateway via an IAM role with s3:GetObject and s3:ListBucket permissions.

Using separate buckets rather than folders within a single bucket provides complete isolation between versions. Each bucket contains an index.html at the root along with hashed JS/CSS assets in an assets/ directory. The identical file structure in both buckets is what makes seamless switching possible.

API Gateway — Traffic Routing with Stage Variables

An API Gateway REST API sits in front of the S3 buckets. It uses an AWS service integration to proxy GET requests directly to S3.

The key mechanism is the path override in the integration configuration:

${stageVariables.bucketName}/{proxy}

This tells API Gateway to resolve the target S3 bucket from a stage variable called bucketName at request time. A proxy resource ({proxy+}) with a URL path parameter mapping (integration.request.path.proxymethod.request.path.proxy) ensures the full file path is forwarded to S3.

Three stages are created from the same deployment:

StagePurposebucketName variable
prodUser-facingPoints to blue or green bucket
blueTesting version 1Always points to blue bucket
greenTesting version 2Always points to green bucket

Binary media types (*/*) are enabled on the API so that JS, CSS, and other static assets are served correctly.

Version Switching — How It Works

Promoting a new version to production is a single update-stage API call that changes the bucketName stage variable on the prod stage. For example, switching from blue to green:

aws apigateway update-stage --rest-api-id {API_ID} --stage-name prod \
  --patch-operations op=replace,path=/variables/bucketName,value=react-app-green-{ACCOUNT_ID}

This takes effect in approximately one second. Rolling back is the same operation pointing back to the original bucket. No new deployment is created — the same API deployment serves different content based on the stage variable value.

SPA Design Considerations

Two design choices in the SPA are critical for this architecture to work:

Relative asset paths: The SPA build must use relative paths (e.g., ./assets/index.js instead of /assets/index.js) for all asset references. Since API Gateway serves the app under a stage prefix (/prod/, /blue/, /green/), absolute paths would resolve to the wrong location. Relative paths ensure the browser loads JS and CSS from the same stage prefix that served the HTML.

Hash-based routing: The SPA uses hash-based routing (/#/about instead of /about). The URL fragment after # is never sent to the server, so every request hits index.html regardless of the client-side route. This eliminates the need for server-side rewrite rules and prevents 404 errors on page refresh.

IAM Role — Secure Access

An IAM role with a trust policy for apigateway.amazonaws.com is created and granted read access to both S3 buckets. This role is specified as the execution role in the API Gateway integration, allowing API Gateway to fetch objects from S3 on behalf of the user without making the buckets public.

Sample Implementation

A complete working implementation with AWS CDK infrastructure code, two React demo applications, build configurations, and deployment scripts is available at:

GitHub: spa_bluegreen_deployment

Related Information

AWS
EXPERT
published a month ago69 views