Serverless Deploy — Deployment Strategies and CI/CD
In this tutorial, you will learn about Serverless Deploy. We cover key concepts, practical examples, and best practices to help you master this topic.
Serverless deployment involves packaging function code, uploading to AWS, updating function configuration, and promoting changes through environments using CI/CD pipelines and deployment strategies.
What You'll Learn
By the end of this lesson you will understand serverless deployment workflows, canary deployments with Lambda aliases, CI/CD pipeline setup, rollback strategies, and environment promotion.
Why It Matters
Serverless deployments are simple in theory but complex in practice. A bad deployment can cause downtime, data loss, or security breaches. Understanding deployment strategies ensures safe, repeatable, and auditable releases.
Real-World Use
DodaBrowser's serverless backend uses a CI/CD pipeline with GitHub Actions. Merging to main triggers a staging deployment, automated tests run against the staging API, and a manual approval gate promotes to production with canary traffic shifting.
flowchart LR
G[Git Push] --> CI[CI Pipeline]
CI --> B[Build Package]
B --> D[Deploy to Dev]
D --> T[Automated Tests]
T -->|Pass| S[Deploy to Staging]
S --> A[Manual Approval]
A --> C[Canary Deploy to Prod]
C --> R[Rollback if Errors]
style D fill:#f90,color:#fff
Deployment with Serverless Framework
The Serverless Framework packages your code, creates a CloudFormation stack, and deploys all resources.
# Deploy all functions and resources
sls deploy --stage production
# Deploy a single function (faster)
sls deploy function -f createUser
# Deploy only the function code without infrastructure changes
sls deploy function -f createUser --update-config
# Package without deploying
sls package --stage production
# deploy_process.py
# Understanding the deployment process
def simulate_deploy(stage="dev"):
steps = [
"1. Validate serverless.yml syntax",
"2. Package function code and dependencies",
"3. Upload to S3 deployment bucket",
"4. Generate CloudFormation template",
"5. Execute CloudFormation stack change set",
"6. Update Lambda function code",
"7. Update Lambda function configuration",
"8. Deploy API Gateway stage",
]
print(f"Deploying to {stage}...\n")
for step in steps:
print(f" {step}")
print(f"\n Stack: my-service-{stage}")
print(f" API URL: https://abc123.execute-api.us-east-1.amazonaws.com/{stage}/")
simulate_deploy("production")
Expected output:
Deploying to production...
1. Validate serverless.yml syntax
2. Package function code and dependencies
3. Upload to S3 deployment bucket
...
API URL: https://abc123.execute-api.us-east-1.amazonaws.com/production/
Canary Deployments
Lambda aliases support canary traffic shifting where a percentage of traffic goes to a new version.
# canary_deploy.py
# Canary deployment simulation
class CanaryDeployment:
def __init__(self, function_name):
self.function = function_name
self.current_version = 1
self.new_version = None
def deploy_canary(self, traffic_percent=5):
self.new_version = self.current_version + 1
print(f"Deploying v{self.new_version} to {self.function}")
print(f" Routing {traffic_percent}% of traffic to new version")
print(" Monitoring errors and latency...")
if traffic_percent <= 10:
print(" -> Canary: No errors detected")
self.promote()
else:
print(" -> Canary: Error rate exceeded threshold")
self.rollback()
def promote(self):
print(f" Promoting v{self.new_version} to 100% traffic")
self.current_version = self.new_version
def rollback(self):
print(f" Rolling back to v{self.current_version}")
deploy = CanaryDeployment("order-api")
deploy.deploy_canary(traffic_percent=5)
Expected output:
Deploying v2 to order-api
Routing 5% of traffic to new version
Monitoring errors and latency...
-> Canary: No errors detected
Promoting v2 to 100% traffic
Rollback Strategies
If a deployment causes issues, rollback to a previous version quickly.
# rollback.py
# Rollback strategies
def simulate_rollback(function_name, deploy_id, reason):
print(f"Rolling back {function_name}")
print(f" Failed deployment: {deploy_id}")
print(f" Reason: {reason}")
print(f" Reverting to previous version...")
steps = [
"Update alias to point to previous version",
"Redeploy previous CloudFormation stack",
"Restore API Gateway stage",
"Clear any warmed execution environments",
]
for s in steps:
print(f" -> {s}")
print(f" Rollback complete. Function restored to previous state.")
simulate_rollback("create-user", "deploy-42", "Error rate exceeded 5% threshold")
CI/CD Pipeline
Set up automated deployment with GitHub Actions, GitLab CI, or AWS CodePipeline.
# .github/workflows/deploy.yml
name: Deploy Serverless
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- run: npm ci
- run: npm test
- name: Deploy to staging
run: npx sls deploy --stage staging
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
Common Mistakes
Deploying directly to production without staging: Always deploy to staging first, run tests, then promote to production.
Not using function-level deployment:
sls deploydeploys everything. Usesls deploy function -f namefor faster iterations.Forgetting to bundle dependencies: Functions fail at runtime with import errors if dependencies are not included in the deployment package.
Not setting up rollback automation: Manual rollbacks take too long during incidents. Automate rollback on error threshold breach.
Ignoring IAM permission drift: When resources are updated outside the Framework, deployments may fail. Use drift detection.
Practice Questions
What is the difference between
sls deployandsls deploy function?sls deploydeploys the entire stack.sls deploy functionupdates only a single function's code.How do canary deployments work with Lambda? Lambda aliases support routing a percentage of traffic to a new version while monitoring for errors.
What should you do if a deployment causes errors? Rollback to the previous version using the alias or redeploy the previous CloudFormation stack.
How do you set up a CI/CD pipeline for serverless? Use GitHub Actions or AWS CodePipeline to run tests on every push and deploy to staging automatically.
Challenge: Create a deployment pipeline that deploys to dev on every PR, staging on merge to main, and production with manual approval and canary traffic shifting.
FAQ
Mini Project
Create a deployment script that packages a serverless function, deploys to staging, runs health check tests, promotes to production with a canary, and rolls back on failure.
import random
def deploy_pipeline():
stages = {
"package": {"status": "pending"},
"deploy-staging": {"status": "pending"},
"tests": {"status": "pending"},
"approve": {"status": "pending"},
"canary-prod": {"status": "pending"},
"promote": {"status": "pending"},
}
for stage in stages:
print(f"[{stage}] Running...")
stages[stage]["status"] = "passed" if random.random() > 0.1 else "failed"
if stages[stage]["status"] == "failed":
print(f"[{stage}] FAILED - Initiating rollback")
for prev in reversed(list(stages.keys())):
if stages[prev]["status"] == "passed":
print(f" Rolling back: {prev}")
stages[prev]["status"] = "rolled-back"
return False
print(f"[{stage}] OK")
print("Deployment complete!")
return True
deploy_pipeline()
What's Next
Next: Serverless Security (IAM) for access control.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro