AWS - Zero downtime Blue/Green deployment for Lambda
If your application is based on Lambda, the Lambda's can be updated in Production with zero downtime using Lambda Versioning and Alias. The Lambda's can be rolled back too easily if something is wrong with the latest code with zero downtime.
Let's see in detail
Understanding some keywords
- Versions - Lambda creates a new version of your function each time that you publish the function. The versioned Lambda's code is frozen and not editable. The version is automatically named 1, 2, 3 and so on each time published and one can't name a version differently
- Aliases - A Lambda alias is like a pointer to a specific Lambda version. Users can invoke the Lambda version using the alias. The Alias can be updated to point to different version
- Blue version - Existing version of Lambda being currently used in Production (In Diagram 2 v2)
- Green version - New version of Lambda being deployed to Production
Keep in mind, Lambda can be invoked in three ways
- Just using its name (e.g. BonusCalculatorLambda). In this case the $LATEST version of the Lambda is invoked by default
- Using its Version (e.g. BonusCalculatorLambda:1). In this case the version 1 of the Lambda is invoked
- Using its Alias (e.g. BonusCalculatorLambda:PROD). In this case the version of the Lambda currently being pointed by the Alias is invoked (As per the Diagram 2 below version 2)
Let's assume your application is built using Spring Boot or Node.js Express and uses multiple Lambdas to implement its business logic and invokes them using AWS SDK as depicted in the following picture. The gateway application is running on ECS Cluster which is exposed to Clients via an ALB. Each of the Lambda can be updated in Production with zero downtime.
Diagram 1 - Lambda based application |
How do we update each Lambda with zero down time and rollback in case something is not good?
Diagram 2 - Before Production deployment state |
Here's how to update the Lambda with zero downtime, the same approach needs to be replicated for each Lambda.
Follow these steps to update the Lambda with changes, refer to Diagram 3 below
- Update the Lambda code using a Jenkins job in Production, this would update the $LATEST version of the Lambda, this is the only version which is open for update, rest of the versions (v1, v2) are frozen and can't be modified
- Test the updated Lambda using a Test User, the Application would invoke $LATEST version of the Lambda based on some criteria such as logged in User (Test User) etc. For real User the Application invokes Lambda using the PROD Alias (e.g. BonusCalculatorLambda:PROD) which would still continue to invoke v2 (Blue) version of the Lambda. Here's a sample Node.js Lambda client
- Once the Test results of $LATEST versions is satisfactory, invoke publish Jenkins job. This would publish v3 of the Lambda. Refer to Diagram 3 below
- As a last step run a Jenkins job to update the Alias PROD so that it starts pointing to v3 (Green) version of Lambda
- In case the deployment needs to be rolled back, just invoke Alias update Jenkins job on the last Pipeline # so that it points back to previous BLUE version v2
During any of this process the Production users are not impacted and the Service is up all time. Replicate this same process for all your Lambdas
Diagram 3 - After deployment of new version in Production |
Here's AWS CLI commands to do all of the things said above, the Lambda is implemented using Node.js:
- Create index.js file with the following line of code
exports.handler = async (event) => {
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
};
return response;
};
- Create a zip file to deploy this code as a Lambda (no .zip extension is necessary, it gets added)
zip BonusCalculatorLambda index.js
- Create the Lambda, make sure you are running this command from the folder where you have BonusCalculatorLambda.zip This creates the $LATEST version of the Lambda
aws lambda create-function --function-name BonusCalculatorLambda \
--role arn:aws:iam::123903503456:role/service-role/roleLambdaExecution \
--runtime nodejs12.x \
--handler index.handler \
--zip-file "fileb://BonusCalculatorLambda.zip
"
- Publish the Lambda to create a version, after this command there would be two version of Lambda 1 and $LATEST, only $LATEST is editable and version 1 is frozen
aws lambda publish-version --function-name BonusCalculatorLambda --description v1
- Create an Alias
aws lambda create-alias --function-name BonusCalculatorLambda \
--name PROD \
--function-version 1
- Update Lambda code, this updates $LATEST version
aws lambda update-function-code --function-name BonusCalculatorLambda \
--zip-file "fileb://BonusCalculatorLambda.zip"
- Upon creating new version 2, update the Alias to point to new version
aws lambda update-alias --function-name BonusCalculatorLambda \
--name PROD --function-version 2
Prerequisite to execute these commands
- One should have setup Client Credentials, see here for instructions
- The Lambda needs a role to Execute (in the example roleLambdaExecution) this should have been created already
- The Client credential one has setup for CLI should have the following Policy action
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::123903503456:role/service-role/roleLambdaExecution"
}
]
}
Note: For the Blue/Green zero downtime deployment it's not necessary your Lambda's should have been exposed via an application (Spring Boot or Node.js Express). It's a sample Architecture explained in this article. The Lambda can be exposed directly via an ALB or API Gateway and the same approach can be used to deploy changes with zero downtime with slight modifications.
No comments:
Post a Comment