Lambda blue-green deployments allow you to release new versions of your Lambda functions with zero downtime by running the old and new versions concurrently and shifting traffic gradually.
Let’s see it in action. Imagine we have a Lambda function named my-processor. We want to deploy a new version that adds a new feature.
First, we define our initial version, let’s call it v1.
{
"FunctionName": "my-processor",
"Runtime": "nodejs18.x",
"Handler": "index.handler",
"Code": {
"S3Bucket": "my-lambda-code-bucket",
"S3Key": "my-processor/v1/code.zip"
},
"Description": "Initial version",
"Timeout": 30,
"MemorySize": 128,
"Environment": {
"Variables": {
"FEATURE_FLAG": "false"
}
}
}
We then publish this as a version:
aws lambda publish-version --function-name my-processor
This returns a version number, say 1. Now, we create an alias, live, that points to v1:
aws lambda create-alias --function-name my-processor --name live --function-version 1
All traffic is now directed to the live alias, which resolves to v1.
Now, we want to deploy v2. We update the function code, but crucially, we don’t update the live alias yet.
{
"FunctionName": "my-processor",
"Runtime": "nodejs18.x",
"Handler": "index.handler",
"Code": {
"S3Bucket": "my-lambda-code-bucket",
"S3Key": "my-processor/v2/code.zip"
},
"Description": "New version with feature enabled",
"Timeout": 30,
"MemorySize": 128,
"Environment": {
"Variables": {
"FEATURE_FLAG": "true"
}
}
}
We publish this as a new version, v2:
aws lambda publish-version --function-name my-processor
This returns version number 2.
The core of blue-green with Lambda lies in using weighted aliases. We’ll create a new alias, let’s call it staging, that initially points to v2.
aws lambda create-alias --function-name my-processor --name staging --function-version 2
Now, we can start shifting traffic from live (which points to v1) to staging (which points to v2) using weights. We can configure the live alias to send a percentage of traffic to v2.
Let’s say we want to send 10% of traffic to v2 for initial testing. We update the live alias to have a traffic-shifting configuration:
aws lambda update-alias --function-name my-processor --name live --function-version 1 --routing-config '{"AdditionalVersionWeights":{"2":0.1}}'
This command tells Lambda: "When someone invokes the live alias, send 90% of the traffic to version 1 and 10% to version 2."
The live alias now has a traffic configuration like this:
{
"Name": "live",
"FunctionVersion": "1",
"Description": "",
"RoutingConfig": {
"AdditionalVersionWeights": {
"2": 0.1
}
},
"LastModified": "2023-10-27T10:30:00+00:00"
}
In this setup, version 1 is the "blue" environment and version 2 is the "green" environment. The live alias acts as the traffic director, allowing us to control the flow.
We monitor our metrics. If everything looks good with 10% of traffic on v2, we can increase the weight:
aws lambda update-alias --function-name my-processor --name live --function-version 1 --routing-config '{"AdditionalVersionWeights":{"2":0.5}}'
This shifts 50% of traffic to v2. We continue this process, increasing the weight incrementally (e.g., 0.75, 0.9, 1.0).
Finally, when we’re confident, we can shift 100% of traffic to v2:
aws lambda update-alias --function-name my-processor --name live --function-version 2 --routing-config '{"AdditionalVersionWeights":{}}'
This command effectively makes version 2 the primary version for the live alias, and version 1 is no longer receiving traffic.
If any issues arise during the rollout, we can immediately roll back by updating the live alias to point back to the stable v1 with 100% weight.
aws lambda update-alias --function-name my-processor --name live --function-version 1 --routing-config '{"AdditionalVersionWeights":{"2":0.0}}'
This is the fundamental mechanism: using multiple versions of your function and an alias with traffic weighting to control the flow between them. The "blue" is the currently stable version, and the "green" is the new version being tested.
What most people miss is that the FunctionVersion in update-alias is the default version that receives traffic if AdditionalVersionWeights is empty or does not cover 100% of the traffic. When you set FunctionVersion to 2 and AdditionalVersionWeights to {"1":0.0}, you’re telling Lambda to route all traffic to v2 and none to v1. If you later want to roll back, you’d set FunctionVersion back to 1 and AdditionalVersionWeights to {"2":0.0}.
Once the new version is fully rolled out and stable, you can clean up the old version by deleting the unused alias or by simply not pointing any traffic to it.
The next step is to automate this process using tools like AWS CodeDeploy or custom CI/CD pipelines that leverage the Lambda alias and versioning APIs.