Skip to content
intermediate Phase 4 · AWS Serverless

Lambda Functions

Write and deploy serverless functions with AWS Lambda.

1h 30m
0 problems
Topic Progress 0%

Lambda Fundamentals

Lambda Fundamentals

AWS Lambda runs code without provisioning or managing servers. You pay only for the compute time consumed.

Supported Runtimes

Runtime Version Handler
Python 3.9-3.12 filename.handler_name
Node.js 18.x, 20.x filename.handler_name
Java 11, 17, 21 package.Class::method
Go 1.x, 2.x handler_name
.NET 6, 8 assembly::namespace.class::method
Ruby 3.2 filename.handler_name
Custom Runtime Any bootstrap

Create a Lambda Function

# Create a Lambda function (Python)
aws lambda create-function \
  --function-name my-function \
  --runtime python3.12 \
  --role arn:aws:iam::123456789012:role/lambda-role \
  --handler lambda_function.lambda_handler \
  --zip-file fileb://function.zip \
  --timeout 30 \
  --memory-size 256 \
  --environment Variables="{DB_HOST=mydb.xxxx.us-east-1.rds.amazonaws.com}"

# Update function code
aws lambda update-function-code \
  --function-name my-function \
  --zip-file fileb://function.zip

# Test function
aws lambda invoke \
  --function-name my-function \
  --payload '{"key": "value"}' \
  output.json

# Check logs
aws logs describe-log-streams --log-group-name /aws/lambda/my-function

Lambda Function Structure

# Python example
import json
import boto3

def lambda_handler(event, context):
    # Event contains trigger data
    print(f"Event: {json.dumps(event)}")
    
    # Context contains runtime info
    print(f"Function: {context.function_name}")
    print(f"Memory: {context.memory_limit_in_mb}MB")
    print(f"Timeout: {context.get_remaining_time_in_millis()}ms remaining")
    
    # Your business logic here
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

Lambda Triggers and Event Sources

Lambda Triggers and Event Sources

S3 Trigger

# Add S3 trigger
aws lambda add-permission \
  --function-name my-function \
  --statement-id s3-trigger \
  --action lambda:InvokeFunction \
  --principal s3.amazonaws.com \
  --source-arn arn:aws:s3:::my-bucket \
  --source-account 123456789012

# Configure S3 notification
aws s3api put-bucket-notification-configuration \
  --bucket my-bucket \
  --notification-configuration '{
    "LambdaFunctionConfigurations": [{
      "LambdaFunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-function",
      "Events": ["s3:ObjectCreated:*"],
      "Filter": {
        "Key": {
          "FilterRules": [{"Name": "prefix", "Value": "uploads/"}]
        }
      }
    }]
  }'

API Gateway Trigger

# The API Gateway integration is configured via API Gateway
# Lambda permission is auto-created by API Gateway

DynamoDB Stream Trigger

# Event source mapping
aws lambda create-event-source-mapping \
  --function-name my-function \
  --event-source-arn arn:aws:dynamodb:us-east-1:xxx:table/MyTable/stream/xxx \
  --starting-position LATEST \
  --batch-size 100 \
  --maximum-batching-window-in-seconds 5

SQS Trigger

aws lambda create-event-source-mapping \
  --function-name my-function \
  --event-source-arn arn:aws:sqs:us-east-1:123456789012:my-queue \
  --batch-size 10

Event Source Types

Source Type Configuration
S3 Asynchronous Bucket notification
API Gateway Synchronous Integration
DynamoDB Streams Event source mapping Stream ARN
SQS Event source mapping Queue ARN
SNS Asynchronous Topic subscription
CloudWatch Events Asynchronous Rule
Kinesis Event source mapping Stream ARN

Lambda Layers and Package Management

Lambda Layers and Package Management

Lambda Layers

Share common code across multiple functions.

# Create a layer
zip -r layer.zip python/

aws lambda publish-layer-version \
  --layer-name my-common-libs \
  --description "Common Python libraries" \
  --compatible-runtimes python3.12 \
  --zip-file fileb://layer.zip

# Attach layer to function
aws lambda update-function-configuration \
  --function-name my-function \
  --layers arn:aws:lambda:us-east-1:123456789012:layer:my-common-libs:1

# List layers
aws lambda list-layer-versions --layer-name my-common-libs

Package Management

# Python - install dependencies
mkdir package
pip install -r requirements.txt -t package/
cd package
zip -r ../function.zip .
cd ..
zip function.zip lambda_function.py

# Node.js
npm install --production
zip -r function.zip node_modules/ lambda_function.js

# Java (Maven)
mvn clean package
# Target/function.jar is your deployment package

Lambda Container Images

FROM public.ecr.aws/lambda/python:3.12

COPY requirements.txt .
pip install -r requirements.txt -t ${LAMBDA_TASK_ROOT}

COPY lambda_function.py ${LAMBDA_TASK_ROOT}

CMD ["lambda_function.lambda_handler"]
# Build and push to ECR
aws ecr create-repository --repository-name my-lambda-image

# Authenticate Docker to ECR
aws ecr get-login-password --region us-east-1 | \
  docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com

# Build and push
docker build -t my-lambda-image .
docker tag my-lambda-image:latest 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-lambda-image:latest
docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-lambda-image:latest

# Create function from container
aws lambda create-function \
  --function-name my-container-function \
  --package-type Image \
  --code ImageUri=123456789012.dkr.ecr.us-east-1.amazonaws.com/my-lambda-image:latest \
  --role arn:aws:iam::xxx:role/lambda-role

Lambda VPC and Networking

Lambda VPC and Networking

VPC Configuration

# Deploy Lambda in VPC
aws lambda update-function-configuration \
  --function-name my-function \
  --vpc-config SubnetIds=subnet-xxx,subnet-yyy,SecurityGroupIds=sg-xxx

# Environment variables for VPC
export DB_HOST=mydb.xxxx.us-east-1.rds.amazonaws.com
export REDIS_HOST=my-redis.xxx.cache.amazonaws.com

VPC Access Considerations

┌─────────────────────────────────────────────────────────────┐
│                    VPC Deployment                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Lambda Function (in VPC)                                   │
│  ├── Can access:                                            │
│  │   • RDS in same VPC                                     │
│  │   • ElastiCache in same VPC                             │
│  │   • EC2 in same VPC                                     │
│  │   • Internal ALB                                         │
│  │                                                         │
│  ├── Needs NAT Gateway for:                                 │
│  │   • AWS API calls (DynamoDB, S3, etc.)                  │
│  │   • Internet access                                     │
│  │                                                         │
│  └── VPC Endpoints (optional):                              │
│      • S3 Gateway Endpoint                                 │
│      • DynamoDB Gateway Endpoint                           │
│      • Other services via Interface Endpoints               │
└─────────────────────────────────────────────────────────────┘

Lambda Destinations

# Configure destinations for async invocations
aws lambda put-function-event-invoke-config \
  --function-name my-function \
  --maximum-retry-attempts 3 \
  --maximum-event-age-in-seconds 3600 \
  --destination-config '{
    "OnSuccess": {
      "Destination": "arn:aws:sqs:us-east-1:123456789012:success-queue"
    },
    "OnFailure": {
      "Destination": "arn:aws:sqs:us-east-1:123456789012:failure-queue"
    }
  }'

Lambda Performance Optimization

Lambda Performance Optimization

Memory and CPU

# Increase memory (also increases CPU proportionally)
aws lambda update-function-configuration \
  --function-name my-function \
  --memory-size 1024  # 1024 MB = 1 vCPU

# Memory-CPU relationship:
# 128-1769 MB: 1 vCPU (partial)
# 1769-3538 MB: 1 vCPU
# 3539-5307 MB: 1.5 vCPU
# 5308-7076 MB: 2 vCPU
# 7077-10615 MB: 3 vCPU

Provisioned Concurrency

# Keep instances warm
aws lambda put-provisioned-concurrency-config \
  --function-name my-function \
  --qualifier live \
  --provisioned-concurrent-executions 10

# Auto-scaling provisioned concurrency
aws application-autoscaling register-scalable-target \
  --service-namespace lambda \
  --scalable-dimension lambda:function:ProvisionedConcurrency \
  --resource-id function:my-function:live \
  --min-capacity 1 \
  --max-capacity 100

aws application-autoscaling put-scaling-policy \
  --service-namespace lambda \
  --scalable-dimension lambda:function:ProvisionedConcurrency \
  --resource-id function:my-function:live \
  --policy-name provisioned-scaling \
  --policy-type TargetTrackingScaling \
  --target-tracking-scaling-policy-configuration '{
    "TargetValue": 0.7,
    "PredefinedMetricSpecification": {
      "PredefinedMetricType": "LambdaProvisionedConcurrencyUtilization"
    }
  }'

SnapStart (Java)

# Enable SnapStart
aws lambda update-function-configuration \
  --function-name my-java-function \
  --snap-start ApplyOn=PublishedVersions

# Cold start: 3000-5000ms → 200-500ms with SnapStart

Performance Best Practices

  1. Minimize deployment package size (exclude boto3, use layers)
  2. Reuse connections (DB, HTTP clients)
  3. Use environment variables for configuration
  4. Set appropriate timeout (not too long, not too short)
  5. Use provisioned concurrency for latency-sensitive functions
  6. Enable SnapStart for Java functions
  7. Use ARM64 (Graviton2) for 20% better price-performance

Lambda Monitoring and Debugging

Lambda Monitoring and Debugging

CloudWatch Logs

# Get log events
aws logs get-log-events \
  --log-group-name /aws/lambda/my-function \
  --log-stream-name 2024/01/15/[$LATEST]xxx

# Filter logs
aws logs filter-log-events \
  --log-group-name /aws/lambda/my-function \
  --filter-pattern "ERROR"

# Create metric filter
aws logs put-metric-filter \
  --log-group-name /aws/lambda/my-function \
  --filter-name error-count \
  --filter-pattern '"ERROR"' \
  --metric-transformations 'metricName=ErrorCount,metricNamespace=Lambda,metricValue=1'

CloudWatch Metrics

# Key Lambda metrics
# - Invocations: Number of function invocations
# - Errors: Number of failed invocations
# - Duration: Execution time (ms)
# - Throttles: Number of throttled invocations
# - ConcurrentExecutions: Current concurrent executions
# - UnreservedConcurrentExecutions: Concurrency not in provisioned pool

aws cloudwatch get-metric-statistics \
  --namespace AWS/Lambda \
  --metric-name Duration \
  --dimensions Name=FunctionName,Value=my-function \
  --start-time $(date -u -d '1 hour ago') \
  --end-time $(date -u) \
  --period 300 \
  --statistics Average Maximum p99

X-Ray Tracing

# Enable X-Ray tracing
aws lambda update-function-configuration \
  --function-name my-function \
  --tracing-config Mode=Active

# View traces
aws xray get-trace-summaries \
  --start-time $(date -u -d '1 hour ago') \
  --end-time $(date -u)