Lab: Automating Deployment Testing with AWS CI/CD and SAM
Automate deployment testing
Lab: Automating Deployment Testing with AWS CI/CD and SAM
In this lab, you will learn how to automate the testing of serverless applications. You will use the AWS Serverless Application Model (SAM) to define your infrastructure and AWS CodeBuild to execute automated unit and integration tests as part of a continuous delivery pipeline.
Prerequisites
Before starting this lab, ensure you have the following:
- An AWS Account with administrative access.
- AWS CLI installed and configured with your credentials.
- AWS SAM CLI installed on your local machine.
- Basic knowledge of Python (for the Lambda function) and YAML (for configuration).
- Git installed locally.
Learning Objectives
By the end of this lab, you will be able to:
- Create application test events and JSON payloads for AWS Lambda.
- Implement and deploy Infrastructure as Code (IaC) templates using AWS SAM.
- Configure AWS CodeBuild to run automated tests during the build phase.
- Differentiate between deployment environments (stages) in Amazon API Gateway.
Architecture Overview
The following diagram illustrates the automated testing and deployment workflow you will build:
The Testing Lifecycle
The cost of fixing bugs increases exponentially as they move toward production. This lab focuses on catching bugs in the "Build" and "Staging" phases.
Step-by-Step Instructions
Step 1: Initialize the SAM Project
We will start with a basic "Hello World" application using the AWS SAM CLI.
sam init --name brainybee-testing-lab --runtime python3.9 --app-template hello-world --package-type Zip
cd brainybee-testing-lab[!TIP] This command creates a directory structure containing a
template.yamlfile (IaC) and ahello_worldfolder for your Lambda code.
Step 2: Create an Automated Unit Test
Navigate to the tests/unit folder. We will ensure the Lambda function returns a 200 OK status code.
# Edit tests/unit/test_handler.py to include a basic assertion
cat <<EOF > tests/unit/test_handler.py
import json
from hello_world import app
def test_lambda_handler():
event = {"body": "test"}
ret = app.lambda_handler(event, "")
assert ret["statusCode"] == 200
assert "message" in ret["body"]
EOFStep 3: Configure the Buildspec for Testing
CodeBuild requires a buildspec.yml file to know how to run your tests. Create this file in the root directory.
cat <<EOF > buildspec.yml
version: 0.2
phases:
install:
runtime-versions:
python: 3.9
commands:
- pip install -r hello_world/requirements.txt
- pip install pytest
pre_build:
commands:
- echo Running unit tests...
- pytest tests/unit/test_handler.py
build:
commands:
- echo Packaging SAM application...
- sam package --output-template-file packaged.yaml --s3-bucket <YOUR_S3_BUCKET_NAME>
artifacts:
files:
- packaged.yaml
EOF▶Console alternative
- Navigate to
in the AWS Console. 2. Create a
. 3. Under
, select "Insert build commands" or point it to the file in your repository.
Step 4: Define Environments in SAM
Update your template.yaml to include a Stage parameter. This allows you to differentiate between dev, test, and prod stages in API Gateway.
Parameters:
Stage:
Type: String
Default: dev
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.9
Events:
HelloWorld:
Type: Api
Properties:
Path: /hello
Method: get
RestApiId: !Ref MyApi
MyApi:
Type: AWS::Serverless::Api
Properties:
StageName: !Ref StageCheckpoints
Checkpoint 1: Local Test Execution
Run your tests locally to ensure the logic is sound before committing to the cloud.
pytest tests/unit/test_handler.pyExpected Result: 1 passed in 0.01s.
Checkpoint 2: Validate SAM Template
sam validateExpected Result: template.yaml is a valid SAM Template.
Clean-Up / Teardown
[!WARNING] Failure to delete these resources may result in unexpected charges to your AWS account.
- Delete the SAM Stack:
bash
sam delete --stack-name brainybee-testing-lab - Delete the S3 Bucket (if created for artifacts):
bash
aws s3 rb s3://<YOUR_S3_BUCKET_NAME> --force - Delete CodeBuild/CodePipeline projects via the console or CLI if you created them manually.
Troubleshooting
| Error | Possible Cause | Fix |
|---|---|---|
sam package fails | Missing S3 bucket or permissions | Ensure bucket exists and CLI has s3:PutObject permissions |
pytest not found | Buildspec install phase failed | Check python version and pip installation steps in buildspec.yml |
| Deployment fails | IAM role for CloudFormation lacks permissions | Ensure the execution role has permissions to create Lambda and API Gateway |
Stretch Challenge
Implement a Lambda Alias for Traffic Shifting:
Modify your template.yaml to include an AutoPublishAlias: live and a DeploymentPreference type like Canary10Percent5Minutes. This automates the "test in production" phase by slowly shifting traffic and rolling back if CloudWatch Alarms trigger.
Cost Estimate
| Service | Estimated Cost (Free Tier) | Estimated Cost (Beyond Free Tier) |
|---|---|---|
| AWS Lambda | First 1M requests free | $0.20 per 1M requests |
| AWS CodeBuild | 100 build minutes/mo free | ~$0.005 per minute |
| Amazon S3 | 5GB Standard storage free | $0.023 per GB |
| Total | $0.00 | < $0.10 for this lab |
Concept Review
| Concept | Description | Real-World Example |
|---|---|---|
| Unit Test | Testing a single function in isolation. | Mocking a DB call to see if your Lambda processes the JSON correctly. |
| Integration Test | Testing the interaction between services. | Deploying to a staging endpoint and sending a real HTTP request to verify API Gateway + Lambda. |
| SAM Template | An extension of CloudFormation for serverless. | Defining your entire backend (API, DB, Auth) in one 100-line YAML file. |
| Buildspec | Instructions for the build server. | Compiling code and running npm test before deployment. |