Skip to main content

Blue-Green Deployments

Deploy Lambda functions with zero downtime using automated blue-green deployment strategies.

Overview

Blue-green deployment is a release management technique that reduces downtime and risk by running two identical production environments: Blue (current) and Green (new). The BlueGreenLambda construct implements this pattern with:

  • Versioned deployments with Lambda aliases
  • CodeDeploy integration for gradual traffic shifting
  • CloudWatch alarms for automatic rollback
  • Environment-specific strategies (immediate, canary, linear)

How It Works

B

Basic Usage

Creating a Blue-Green Lambda

import { BlueGreenLambda } from '../lib/lambda/BlueGreenLambda';
import { Stack } from '@root/aws-cdk-lib';
import { Sdlc } from '@root/types/global/ContextStrategy';

interface MyStackProps {
sdlc: Sdlc;
}

export class MyStack extends Stack {
constructor(scope: Construct, id: string, props: MyStackProps) {
super(scope, id);

const { sdlc } = props;

// Create Lambda with blue-green deployment
const lambda = new BlueGreenLambda(this, 'MyFunction', {
sdlc,
functionName: 'MyAPI',
entry: './lib-src/lambda/myApi/src/index.ts',
environment: {
TABLE_NAME: myTable.tableName,
},
});

// Always use the production alias for integrations
const apiFunction = lambda.getFunction();
}
}

Deployment Configurations by Environment

The library automatically selects deployment strategies based on the environment:

EnvironmentStrategyBehavior
devAll-at-onceImmediate deployment, no gradual shift
stagingCanary10Percent5Minutes10% traffic, then 100% after 5 minutes
prodLinear10PercentEvery10Minutes10% every 10 minutes until 100%

Advanced Configuration

Custom Timeout and Memory

const lambda = new BlueGreenLambda(this, 'MyFunction', {
sdlc,
functionName: 'MyAPI',
entry: './lib-src/lambda/myApi/src/index.ts',
timeout: Duration.seconds(30),
memorySize: 512,
});

The Lambda Function

import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';

export async function handler(
event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> {
const sdlc = process.env.SDLC;
const version = process.env.AWS_LAMBDA_FUNCTION_VERSION;

console.log(`Handling request in ${sdlc}, version ${version}`);

return {
statusCode: 200,
body: JSON.stringify({ message: 'Success!' }),
};
}

Automatic Rollback

The construct creates CloudWatch alarms that monitor error rates and automatically trigger rollbacks:

Error Thresholds by Environment

  • Dev: 5 errors in 60 seconds
  • Staging: 3 errors in 60 seconds
  • Production: 1 error in 60 seconds

Rollback Triggers

Automatic rollback occurs when:

  1. Error rate exceeds threshold during deployment
  2. Deployment fails for any reason
  3. Deployment is manually stopped
// The deployment group automatically handles rollback
this.deploymentGroup = new LambdaDeploymentGroup(this, 'DeploymentGroup', {
alias: this.productionAlias,
alarms: [this.errorAlarm],
autoRollback: {
failedDeployment: true,
stoppedDeployment: true,
deploymentInAlarm: true,
},
});

Integration with API Gateway

Always integrate API Gateway with the production alias, not the function directly:

import { RestApi, LambdaIntegration } from '@root/aws-cdk-lib';

const api = new RestApi(this, 'MyApi', {
restApiName: `my-api-${sdlc}`,
});

// Use the production alias
const integration = new LambdaIntegration(lambda.getFunction());

api.root.addMethod('GET', integration);

Monitoring Deployments

View Deployment Status

# Check current deployments
aws deploy list-deployments \
--application-name MyApp \
--deployment-group-name MyFunction-prod

# Get deployment details
aws deploy get-deployment \
--deployment-id d-XXXXXXXXX

CloudWatch Metrics

Monitor these metrics during deployment:

  • Errors - Lambda function errors
  • Throttles - Throttled invocations
  • Duration - Execution time
  • ConcurrentExecutions - Concurrent invocations

Using the Deployment Scripts

# Check deployment status
npm run deployment:status

# Rollback if needed
npm run deployment:rollback

Deployment Workflow

1. Code Change

# Make changes to your Lambda
vim lib-src/lambda/myApi/src/index.ts

# Commit changes
git add .
git commit -m "feat: add new feature"

2. Deploy

# Deploy to dev (immediate)
npm run deploy:dev

# Deploy to staging (canary)
npm run deploy:staging

# Deploy to production (linear)
npm run deploy:prod

3. Monitor

Watch CloudWatch metrics and logs during deployment:

# Tail logs
aws logs tail /aws/lambda/MyAPI-prod --follow

# Check metrics
aws cloudwatch get-metric-statistics \
--namespace AWS/Lambda \
--metric-name Errors \
--dimensions Name=FunctionName,Value=MyAPI-prod

4. Rollback (if needed)

# Automatic rollback on alarm
# OR manual rollback
npm run deployment:rollback

CI/CD Integration

GitHub Actions Example

name: Deploy Lambda

on:
push:
branches: [main]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1

- name: Install Dependencies
run: npm ci

- name: Deploy
run: npm run deploy:prod

- name: Monitor Deployment
run: npm run deployment:status

Best Practices

  1. Always use production alias: Integrate with lambda.getFunction(), never the Lambda directly
  2. Test in lower environments first: Deploy to dev → staging → prod
  3. Monitor during deployment: Watch CloudWatch metrics and logs
  4. Set appropriate thresholds: Adjust error thresholds based on your application
  5. Version your functions: Each deployment creates a new immutable version
  6. Use environment variables: Pass configuration via environment variables
  7. Enable X-Ray tracing: Add tracing for better observability
const lambda = new BlueGreenLambda(this, 'MyFunction', {
sdlc,
functionName: 'MyAPI',
entry: './lib-src/lambda/myApi/src/index.ts',
environment: {
ENABLE_XRAY: 'true',
LOG_LEVEL: sdlc === 'prod' ? 'INFO' : 'DEBUG',
},
});

Troubleshooting

Deployment Stuck

If a deployment is stuck in progress:

# Stop the deployment (triggers rollback)
aws deploy stop-deployment \
--deployment-id d-XXXXXXXXX \
--auto-rollback-enabled

High Error Rates

Check Lambda logs and metrics:

# View recent errors
aws logs filter-log-events \
--log-group-name /aws/lambda/MyAPI-prod \
--filter-pattern "ERROR"

Manual Rollback

# List recent deployments
npm run deployment:status

# Rollback to previous version
npm run deployment:rollback