Serverless Scheduling
Using Python Step Functions
bene@theodo.co.uk
Ben Ellerby
@EllerbyBen
@EllerbyBen
serverless-transformation
@EllerbyBen
@EllerbyBen
Serverless
What is this Serverless thing?
-
Architectural movement
- Developers send application code which is run by the cloud provider in isolated containers abstracted from the developer.
- Use 3rd party services used to manage backend logic and state (e.g. Firebase, Cognito)
- A framework with the same name
@EllerbyBen
Why Serverless?
💰 Cost reduction
👷♂️ #NoOps
💻 Developers focus on delivering business value
📈 More scalable
🌳 Greener
@EllerbyBen
Not just Lambda (FaaS)
Lambda
S3
Dynamo
API Gateway
Compute
Storage
Data
API Proxy
Cognito
Auth
SQS
Queue
Step Functions
Workflows
Power and Flexibility
@EllerbyBen
FaaS: AWS Lambda
@EllerbyBen
@EllerbyBen
Lambda
Runtimes
@EllerbyBen
Runtimes
@EllerbyBen
@EllerbyBen
3.7, 3.6, 2.7
A Simple Function
@EllerbyBen
def handler_name(event, context):
...
return some_value
Event: The event body
dict, list, str, int, float, or NoneType
Context: Meta Data
dict
A Simple Function
@EllerbyBen
def my_handler(event, context):
message = 'Hello {} {}!'.format(event['first_name'],
event['last_name'])
return {
'message' : message
}
Handler Function
@EllerbyBen
A handler function is a function of your code triggered by AWS when your lambda is invoked
Serverless... Framework
@EllerbyBen
Serverless... Framework
@EllerbyBen
npm install -g serverless
serverless create
--template aws-python3
--path myService
@EllerbyBen
serverless.yml
handler.py
Handler
@EllerbyBen
import json
def hello(event, context):
body = {
"message": "Go Serverless v1.0! Your function executed successfully!",
"input": event
}
response = {
"statusCode": 200,
"body": json.dumps(body)
}
return response
serverless.yml
@EllerbyBen
service: myService
provider:
name: aws
runtime: python3.7
functions:
hello:
handler: handler.hello
local
@EllerbyBen
➜ sls invoke local -f hello
{
"statusCode": 200,
"body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": {}}"
}
deploy
@EllerbyBen
➜ sls deploy
➜ sls invoke -f hello
{
"statusCode": 200,
"body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": {}}"
}
Lambda Triggers
@EllerbyBen
Scheduling Emails
@EllerbyBen
Scheduling Anything
@EllerbyBen
?
Celery
@EllerbyBen
- Requires Message Broker
- e.g RabbitMQ
- Distributed Task Queue
- Defines a workflow
- e.g. task 1, task 2 + 3, task 4
- Distributed
- Defines a workflow
Celery Beat
@EllerbyBen
Polls database
Celery beat is a scheduler; It kicks off tasks at regular intervals, that are then executed by available worker nodes in the cluster.
@EllerbyBen
SQL DB
App
App
Rabbit MQ
Celery
Celery
Celery
Celery
Beat
@EllerbyBen
SQL DB
App
App
Rabbit MQ
Celery
Celery
Celery
Celery
Beat
@EllerbyBen
Step Functions
@EllerbyBen
Step Functions
AWS Step Functions lets you coordinate multiple AWS services into serverless workflows so you can build and update apps quickly.
@EllerbyBen
Step Functions
@EllerbyBen
Cloudformation
AWSTemplateFormatVersion: '2010-09-09'
Description: An example template for a Step Functions state machine.
Resources:
MyStateMachine:
Type: AWS::StepFunctions::StateMachine
Properties:
StateMachineName: HelloWorld-StateMachine
DefinitionString: |-
{
"StartAt": "HelloWorld",
"States": {
"HelloWorld": {
"Type": "Task",
"Resource": "ARN of Function.....",
"End": true
}
}
}
RoleArn: arn-of-role
Tags:
-
Key: "keyname1"
Value: "value1"
-
Key: "keyname2"
Value: "value2"
@EllerbyBen
serverless-step-functions
@EllerbyBen
serverless-step-functions
stepFunctions:
stateMachines:
MyStateMachine:
name: MyMachine
definition:
Comment: "Does something cool"
States:
HelloWorld:
Type: Task
Resource: "HelloLambdaARN"
End: true
@EllerbyBen
FIFO
Date Queue
+
@EllerbyBen
First In
Date Out
+
@EllerbyBen
FIDO
@EllerbyBen
@EllerbyBen
@EllerbyBen
Start
Wait
Push
End
@EllerbyBen
Start
Wait
Push
End
@EllerbyBen
You are charged based on the number of state transitions required to execute your application.
Start
Wait
Push
End
12/10/2019
push_email
send_email
schedule_email
@EllerbyBen
stepFunctions:
stateMachines:
EmailFSM:
name: EmailScheduling
definition:
Comment: "Schedules an email"
StartAt: WaitForDueDate
States:
WaitForDueDate:
Type: Wait
TimestampPath: $.dueDate
Next: PushEmail
PushEmail:
Type: Task
Resource: "arn-of-function"
End: true
FSM
@EllerbyBen
service: myService
provider:
name: aws
runtime: python3.7
functions:
hello:
handler: handler.send_email
events:
- sqs:
arn:
Fn::GetAtt:
- EmailQueue
- Arn
resources:
Resources:
EmailQueue:
Type: "AWS::SQS::Queue"
Properties:
QueueName: "EmailQueue${opt:infraStackName}"
SQS
@EllerbyBen
{
"dueDate": "2019-03-26T00:00:00.000Z",
"from ": "bene@theodo.co.uk",
"to": "pycon@theodo.co.uk",
"subject": "serverless"
}
event
@EllerbyBen
def schedule_email(event, context):
sfn = boto3.client('stepfunctions')
sfn_response = sfn.start_execution(
stateMachineArn=os.environ.get('SFN_ARN'),
name=event.schedule,
input=event['body']
)
response = {
"statusCode": 200,
"body": event['body']
}
return response
schedule_email
@EllerbyBen
def push_email(event, context):
client = boto3.client('sqs')
sqs_event = client.send_message(
QueueUrl=os.environ['SQS_URL'],
MessageBody=event['body']
)
response = {
"statusCode": 200,
"body": "EVENT PUSHED"
}
return response
push_email
@EllerbyBen
def send_email(event, context):
message = Mail(
from_email=event['body']['from'],
to_emails=event['body']['to'],
subject=event['body']['subject'],
html_content='Hello PyCon!'
)
sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
response = sg.send(message)
print(response.status_code)
print(response.body)
print(response.headers)
response = {
"statusCode": 200,
"body": "Email Sent"
}
return response
send_email
Conclusion
-
Step functions provide a nice way to create workflows
-
AWS provides good serverless services for python
The serverless framework with plugins can manage event scheduling
@EllerbyBen
serverless-transformation
@EllerbyBen
npm install -g sls-dev-tools
@EllerbyBen
Serverless Scheduling - Using Python Step Functions in AWS
By Ben Ellerby
Serverless Scheduling - Using Python Step Functions in AWS
Talk given at the AWS Community Summit.
- 1,023