What is Serverless?
No servers to manage. You write code, cloud provider handles:
- Provisioning
- Scaling
- Patching
- Monitoring
You pay only for execution time/invocations.
Functions as a Service (FaaS)
AWS Lambda
Write functions, triggered by events. Pay per invocation + GB-seconds.
# Create function
cat > lambda_function.py << 'EOF'
def lambda_handler(event, context):
return {
'statusCode': 200,
'body': 'Hello from Lambda!'
}
EOF
zip function.zip lambda_function.py
aws lambda create-function \
--function-name hello-world \
--runtime python3.9 \
--role arn:aws:iam::ACCOUNT:role/lambda-role \
--handler lambda_function.lambda_handler \
--zip-file fileb://function.zip
# Invoke
aws lambda invoke \
--function-name hello-world \
--payload '{"key": "value"}' response.json
cat response.jsonTriggers
# Trigger from S3 upload
aws lambda create-event-source-mapping \
--event-source-arn arn:aws:s3:::my-bucket \
--function-name my-function \
--enabled
# Trigger from API Gateway
aws apigateway create-rest-api --name myapi
# Trigger from CloudWatch (schedule)
aws events put-rule --name my-schedule --schedule-expression "rate(5 minutes)"
aws events put-targets --rule my-schedule --targets "Id"="1","Arn"="arn:aws:lambda:..."Azure Functions
# Create function app
az functionapp create \
--name myapp \
--resource-group myRG \
--runtime python \
--runtime-version 3.9 \
--functions-version 4
# Create HTTP function
az functionapp function create \
--name myapp \
--function-name hello \
--template "HTTP trigger" \
--resource-group myRGGCP Cloud Functions
# Create function
cat > main.py << 'EOF'
def hello_world(request):
return 'Hello from Cloud Functions!'
EOF
gcloud functions deploy hello-world \
--runtime python39 \
--trigger-http \
--allow-unauthenticatedContainers (Serverless)
Run containers without managing Kubernetes
AWS Fargate (ECS)
# Create task definition
aws ecs register-task-definition \
--family hello-world \
--network-mode awsvpc \
--requires-compatibilities FARGATE \
--cpu 256 \
--memory 512 \
--container-definitions '[{"name": "hello", "image": "nginx:latest", "portMappings": [{"containerPort": 80}]}]'
# Create service
aws ecs create-service \
--cluster my-cluster \
--service-name hello \
--task-definition hello-world \
--desired-count 1 \
--launch-type FARGATEAzure Container Instances
# Create container
az container create \
--resource-group myRG \
--name mycontainer \
--image nginx \
--ports 80
# Get IP
az container show --resource-group myRG --name mycontainer --query ipAddress.ipGCP Cloud Run
# Deploy container
gcloud run deploy hello \
--image gcr.io/my-project/hello \
--platform managed \
--region us-central1 \
--allow-unauthenticated
# Scales to zero when unusedServerless Databases
AWS DynamoDB (Serverless)
Pay per request, scales automatically
aws dynamodb create-table \
--table-name Users \
--attribute-definitions AttributeName=UserID,AttributeType=S \
--key-schema AttributeName=UserID,KeyType=HASH \
--billing-mode PAY_PER_REQUEST # Serverless!Firestore (Serverless)
# Full serverless - no infrastructure
gcloud firestore databases create --location=us-central1 --type=DATASTORE_MODEAPI Gateway
Build stateless APIs
AWS API Gateway
# Create REST API
aws apigateway create-rest-api \
--name my-api \
--description "My serverless API"
# Create resource
aws apigateway create-resource \
--rest-api-id xxxxx \
--parent-id rrrr \
--path-part users
# Create method
aws apigateway put-method \
--rest-api-id xxxxx \
--resource-id rrrr \
--http-method GET \
--authorization-type NONE
# Integrate with Lambda
aws apigateway put-integration \
--rest-api-id xxxxx \
--resource-id rrrr \
--http-method GET \
--type AWS_PROXY \
--integration-http-method POST \
--uri arn:aws:apigateway:...:lambda:path/2015-03-31/functions/arn:aws:lambda:.../invocations
# Deploy
aws apigateway create-deployment --rest-api-id xxxxx --stage-name prodGCP API Gateway
# openapi.yaml
openapi: 3.0.0
info:
title: My API
servers:
- url: https://api.example.com
paths:
/users:
get:
x-google-backend:
address: https://region-project.cloudfunctions.net/getUsersgcloud api-gateway apis create my-api
gcloud api-gateway api-configs create prod --api my-api --openapi-spec openapi.yamlMonitoring Serverless
AWS CloudWatch
# View logs
aws logs tail /aws/lambda/my-function --follow
# Get metrics
aws cloudwatch get-metric-statistics \
--namespace AWS/Lambda \
--metric-name Duration \
--start-time 2024-01-01T00:00:00Z \
--end-time 2024-01-02T00:00:00Z \
--period 3600 \
--statistics Average
# Create alarm
aws cloudwatch put-metric-alarm \
--alarm-name lambda-errors \
--metric-name Errors \
--namespace AWS/Lambda \
--statistic Sum \
--period 300 \
--threshold 1 \
--comparison-operator GreaterThanOrEqualToThresholdGCP Cloud Logging
# Tail logs
gcloud functions logs read hello-world --limit 100 --follow
# Query logs
gcloud logging read "resource.type=cloud_function AND resource.labels.function_name=hello-world"Pricing Comparison
AWS Lambda
$0.20 per 1 million requests
$0.0000166667 per GB-second (usually $0.50 per GB-month)
Free tier: 1 million requests + 400,000 GB-seconds/month
Azure Functions
$0.20 per million invocations
$0.000016667 per GB-second (usually $0.500 per GB-month)
First 1 million invocations free
GCP Cloud Functions
$0.40 per million invocations
$0.0000025 per GB-second
First 2 million invocations free
Best Practices
✅ Keep functions small and focused ✅ Use managed services (no self-managed infrastructure) ✅ Monitor cold start times ✅ Set timeout appropriately ✅ Use environment variables for configuration ✅ Version your functions ✅ Test locally before deploying ✅ Set resource limits (memory, concurrency)
❌ Don't assume functions are fast (cold starts) ❌ Don't store state in function code ❌ Don't forget to set timeouts ❌ Don't debug in production