Serverless Framework in a few lines¶
A Serverless Framework functions: entry is short because the framework writes the rest. This is the usual
example, a Python function that runs on a schedule:
functions:
worker:
handler: handler.cleanup
runtime: python3.12
memorySize: 512
timeout: 600
events:
- schedule: cron(0 3 * * ? *)
The framework expands it into a CloudFormation template of about 120 lines. You never see that template unless you
run sls package. The same function as patterns, from
examples/serverless.py:
import cfn_typed as cfn
from cfn_types import lambda_
from cfn_typed_sumo.constructs import function, schedule
def build() -> cfn.Template:
worker = function(
"Worker",
code=lambda_.FunctionCode(S3Bucket="deploy-artifacts", S3Key="my-service/package.zip"),
handler="handler.cleanup",
runtime="python3.12",
memory=512,
timeout=600,
)
return {
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": cfn.combine(worker, schedule("Worker", "cron(0 3 * * ? *)", worker.function)),
}
It renders to the template below, committed as
serverless.yaml and
checked by the test suite:
AWSTemplateFormatVersion: '2010-09-09'
Resources:
WorkerRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- !Sub arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
WorkerLogs:
Type: AWS::Logs::LogGroup
Properties:
RetentionInDays: 30
Worker:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: deploy-artifacts
S3Key: my-service/package.zip
Handler: handler.cleanup
Runtime: python3.12
MemorySize: 512
Timeout: 600
Role: !GetAtt WorkerRole.Arn
LoggingConfig:
LogGroup: !Ref WorkerLogs
WorkerRule:
Type: AWS::Events::Rule
Properties:
ScheduleExpression: cron(0 3 * * ? *)
State: ENABLED
Targets:
- Id: Target0
Arn: !GetAtt Worker.Arn
WorkerPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref Worker
Principal: events.amazonaws.com
SourceArn: !GetAtt WorkerRule.Arn
What is the same, and what is not¶
The call is longer than the YAML, and the output is shorter than the framework's. Both differences are about where the work is done.
| Serverless Framework | Patterns | |
|---|---|---|
| Function, role, log group | generated | function creates WorkerRole, WorkerLogs and Worker |
| Schedule and invoke permission | generated | schedule creates WorkerRule and WorkerPermission |
| Log group retention | none by default | 30 days, an argument |
| Code packaging and upload | built in | not done: Code points at an object you uploaded |
| Deployment bucket and its policy | generated | not done |
| A new Lambda version per deploy | generated | not done; see live_alias in CDK L2 constructs |
| Where you see the output | sls package |
in the call, in the committed YAML |
A misspelled MemorySize |
caught when you deploy | caught by ty before you run anything |
The patterns produce 47 lines because they leave out the packaging half of the framework. If you only want the
CloudFormation side, that is the part you need: upload the zip with aws s3 cp or your CI, and pass the key. If
you want the framework to package and upload for you, a pattern is not a replacement.
The IAM role is also narrower. The framework's role gets the permissions you list under iamRoleStatements, and
here they are the statements argument of function, taking the same statements as grants:
Moving an existing service¶
To move a running service without replacing anything, see Ejecting from the Serverless Framework: it imports the
template sls package writes and keeps its logical IDs. What follows is the manual way.
Capture what the framework generates and compare it with what the code renders:
sls package, then take.serverless/cloudformation-template-update-stack.json.- Build the same resources with the patterns and render them.
- Create a change set without executing it:
aws cloudformation deploy --no-execute-changeset, thenaws cloudformation describe-change-set.
A resource whose logical ID changes is a replacement, so the names matter. The framework derives them
(WorkerLambdaFunction, WorkerLogGroup), while a pattern derives them from name. Name the pattern calls so
the IDs match, or accept the replacement for stateless resources.