AWS for DevOps — Lambda Basics
9.1 — Lambda Basics
AWS Lambda runs your code without provisioning or managing servers. Upload your code, configure a trigger, and Lambda handles everything — scaling, high availability, and patching.
How Lambda Works
Event (API call, S3 upload, schedule)
│
▼
Lambda Service
┌──────────────────────────┐
│ Provisions a container │
│ Loads your code │
│ Runs the handler │
│ Returns response │
│ Container stays warm │ ◀── reused for next invocation
└──────────────────────────┘
│
▼
Result (response, logs to CloudWatch)
Creating a Lambda Function
handler.py:
import json
def lambda_handler(event, context):
"""
event — the input data (JSON)
context — runtime info (function name, memory, timeout remaining)
"""
name = event.get('name', 'World')
return {
'statusCode': 200,
'body': json.dumps({
'message': f'Hello, {name}!'
})
}
# Zip the code
$ zip function.zip handler.py
# Create the function
$ aws lambda create-function \
--function-name hello-world \
--runtime python3.12 \
--handler handler.lambda_handler \
--role arn:aws:iam::123456789012:role/LambdaExecutionRole \
--zip-file fileb://function.zip \
--timeout 30 \
--memory-size 256
{
"FunctionName": "hello-world",
"FunctionArn": "arn:aws:lambda:ap-south-1:123456789012:function:hello-world",
"Runtime": "python3.12",
"Handler": "handler.lambda_handler"
}
Invoking a Function
# Synchronous invocation
$ aws lambda invoke \
--function-name hello-world \
--payload '{"name": "DevOps Engineer"}' \
--cli-binary-format raw-in-base64-out \
output.json
$ cat output.json
{"statusCode": 200, "body": "{\"message\": \"Hello, DevOps Engineer!\"}"}
Lambda Configuration
| Setting | Default | Max | Notes |
|---|---|---|---|
| Memory | 128 MB | 10,240 MB | CPU scales proportionally with memory |
| Timeout | 3 seconds | 900 seconds (15 min) | Function killed if exceeded |
| Ephemeral storage | 512 MB | 10,240 MB | /tmp directory |
| Concurrency | 1,000 | Account limit (request increase) | Concurrent executions |
| Package size | — | 50 MB (zip), 250 MB (unzipped) | Use layers for large dependencies |
Environment Variables
$ aws lambda update-function-configuration \
--function-name hello-world \
--environment 'Variables={DB_HOST=mydb.abc.rds.amazonaws.com,LOG_LEVEL=info}'
For secrets, use SSM Parameter Store or Secrets Manager with the Lambda Powertools library — never store secrets as plaintext environment variables.
Lambda Layers
Layers let you share code and dependencies across multiple functions:
# Create a layer from a zip (must follow directory structure)
# python/lib/python3.12/site-packages/<your packages>
$ zip -r my-layer.zip python/
$ aws lambda publish-layer-version \
--layer-name my-shared-libs \
--compatible-runtimes python3.12 \
--zip-file fileb://my-layer.zip
# Attach layer to a function
$ aws lambda update-function-configuration \
--function-name hello-world \
--layers arn:aws:lambda:ap-south-1:123456789012:layer:my-shared-libs:1
Versions and Aliases
# Publish a version (immutable snapshot)
$ aws lambda publish-version --function-name hello-world
{
"Version": "1",
"FunctionArn": "arn:aws:lambda:ap-south-1:123456789012:function:hello-world:1"
}
# Create an alias pointing to version 1
$ aws lambda create-alias \
--function-name hello-world \
--name production \
--function-version 1
# Shift traffic: 90% to v1, 10% to v2 (canary)
$ aws lambda update-alias \
--function-name hello-world \
--name production \
--function-version 2 \
--routing-config AdditionalVersionWeights={"1"=0.9}
Cold Starts
| Aspect | Detail |
|---|---|
| What | First invocation spins up a new container (~100ms to 2s) |
| When | After idle period, or when scaling out new instances |
| Mitigation | Provisioned Concurrency, smaller packages, choose fast runtimes |
# Provisioned Concurrency — keep N containers warm
$ aws lambda put-provisioned-concurrency-config \
--function-name hello-world \
--qualifier production \
--provisioned-concurrent-executions 5
Common Mistakes
| Mistake | Why It Hurts | Fix |
|---|---|---|
| Timeout too short | Function killed mid-execution | Set timeout based on actual execution time + buffer |
| Too little memory | Slow execution (CPU scales with memory) | Increase memory — often cheaper overall |
| Huge deployment package | Slow cold starts | Use layers, exclude dev dependencies |
| No dead letter queue | Failed async invocations lost | Configure DLQ (SQS or SNS) |
Quick Reference
| Task | Command |
|---|---|
| Create function | aws lambda create-function --function-name NAME --runtime python3.12 --handler handler.lambda_handler --role ROLE --zip-file fileb://code.zip |
| Invoke | aws lambda invoke --function-name NAME --payload '{}' output.json |
| Update code | aws lambda update-function-code --function-name NAME --zip-file fileb://code.zip |
| Update config | aws lambda update-function-configuration --function-name NAME --memory-size 512 |
| View logs | aws logs tail /aws/lambda/NAME --follow |
Next → API Gateway