Skip to content

Commit d7c948f

Browse files
authored
feat: Add aws-ruby-step-functions example (serverless#632)
1 parent 7f4ad28 commit d7c948f

File tree

23 files changed

+15970
-1
lines changed

23 files changed

+15970
-1
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@ serverless install -u https://github.com/serverless/examples/tree/master/folder-
125125
| [Aws Ruby Line Bot](https://github.com/serverless/examples/tree/master/aws-ruby-line-bot) <br/> Example demonstrates how to setup a simple Line echo bot on AWS | ruby |
126126
| [Aws Ruby Simple Http Endpoint](https://github.com/serverless/examples/tree/master/aws-ruby-simple-http-endpoint) <br/> Example demonstrates how to setup a simple HTTP GET endpoint | ruby |
127127
| [Aws Ruby Sinatra Dynamodb Api](https://github.com/serverless/examples/tree/master/aws-ruby-sinatra-dynamodb-api) <br/> Example of a Ruby Sinatra API service backed by DynamoDB with traditional Serverless Framework | ruby |
128-
| [Serverless Ruby SQS Dynamodb](https://github.com/serverless/examples/tree/master/aws-ruby-sqs-with-dynamodb) <br/> A serverless ruby example that creates DynamoDB records with usage of SQS, API Gateway, and AWS Lambda functions | ruby |
128+
| [Serverless Ruby Sqs Dynamodb](https://github.com/serverless/examples/tree/master/aws-ruby-sqs-with-dynamodb) <br/> A serverless ruby example that creates DynamoDB records with the usage of SQS, API Gateway, and AWS Lambda functions. | ruby |
129+
| [Serverless Ruby Sqs Dynamodb](https://github.com/serverless/examples/tree/master/aws-ruby-sqs-with-dynamodb/src) <br/> A serverless ruby example that creates DynamoDB records with usage of SQS, API Gateway, and AWS Lambda functions | ruby |
130+
| [Aws Ruby Step Functions](https://github.com/serverless/examples/tree/master/aws-ruby-step-functions) <br/> Ruby example that make usage of AWS Step Functions with AWS Lambda, DynamoDB and Step Functions flows. | ruby |
129131
| [Aws Rust Simple Http Endpoint](https://github.com/serverless/examples/tree/master/aws-rust-simple-http-endpoint) <br/> Example demonstrates how to setup a simple HTTP GET endpoint with rust | nodeJS |
130132
| [Azure Nodejs](https://github.com/serverless/examples/tree/master/azure-node-line-bot) <br/> Azure Functions sample for the Serverless framework | nodeJS |
131133
| [Azure Node Simple Http Endpoint](https://github.com/serverless/examples/tree/master/azure-node-simple-http-endpoint) <br/> An example of making http endpoints with the Azure Functions Serverless Framework plugin | nodeJS |

aws-ruby-step-functions/Gemfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
source 'https://rubygems.org'
2+
3+
gem 'aws-sdk-dynamodb'

aws-ruby-step-functions/README.md

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
<!--
2+
title: 'Ruby AWS Ruby Step Functions'
3+
description: 'Ruby example that make usage of AWS Step Functions with AWS Lambda, DynamoDB and Step Functions flows.'
4+
layout: Doc
5+
framework: v2
6+
platform: AWS
7+
language: Ruby
8+
authorLink: 'https://github.com/pigius'
9+
authorName: 'Daniel Aniszkiewicz'
10+
authorAvatar: 'https://avatars1.githubusercontent.com/u/8863200?s=200&v=4'
11+
-->
12+
# Serverless AWS Ruby Step Functions
13+
14+
This is an example of using `AWS Step Functions` `Standard` Workflow Type. It uses `AWS Lambda`, `DynamoDB` (create and update, 2 separate databases), and `flows` from `Step Functions`.
15+
16+
17+
## Diagram
18+
19+
![diagram](./images/step-functions-diagram.png)
20+
21+
The workflow used as an example is organising a holiday for example out of town.
22+
23+
Here we have two dynamodb tables:
24+
25+
- `tickets` table for tickets
26+
- `parking-lot-spaces` table for parking spaces
27+
28+
29+
The workflow first creates a record for us to buy a ticket, and to book a parking space (as Parallel state), and then waits for the day on which the tour is to take place (Wait State timestamp as check_in_date), and it checks the weather.
30+
31+
Depending on the weather, the workflow is successful if the weather is good. Otherwise (bad weather), both the ticket and the parking space are cancelled.
32+
33+
This can be considered a Saga pattern.
34+
35+
![detailed-diagram](./images/step-functions-detailed.png)
36+
37+
## Setup
38+
39+
`npm install` to install all needed packages.
40+
41+
## Deployment
42+
43+
In order to deploy the service run:
44+
45+
```bash
46+
sls deploy
47+
```
48+
49+
for deploying with a specific `profile` (located in `~/.aws/credentials`) you can simply use the command:
50+
51+
```bash
52+
AWS_PROFILE=YOUR_PROFILE_NAME sls deploy
53+
```
54+
55+
for deploying to the specific stage, let's say `staging` do:
56+
57+
```bash
58+
sls deploy --stage staging
59+
```
60+
61+
The expected result should be similar to:
62+
63+
```bash
64+
Serverless: Packaging service...
65+
Serverless: Excluding development dependencies...
66+
Serverless: Clearing previous build ruby layer build
67+
[ '2.2' ]
68+
Serverless: Installing gem using local bundler
69+
Serverless: Zipping the gemfiles to ../examples/aws-ruby-step-functions/.serverless/ruby_layer/gemLayer.zip
70+
Serverless: Configuring Layer and GEM_PATH to the functions
71+
✓ State machine "myStateMachine" definition is valid
72+
Serverless: Uploading CloudFormation file to S3...
73+
Serverless: Uploading artifacts...
74+
Serverless: Uploading service serverless-ruby-step-functions.zip file to S3 (1.03 MB)...
75+
Serverless: Uploading service gemLayer.zip file to S3 (640.83 KB)...
76+
Serverless: Validating template...
77+
Serverless: Updating Stack...
78+
Serverless: Checking Stack update progress...
79+
.................................................................................
80+
Serverless: Stack update finished...
81+
Service Information
82+
service: serverless-ruby-step-functions
83+
stage: dev
84+
region: us-east-1
85+
stack: aws-ruby-step-functions-dev
86+
resources: 23
87+
api keys:
88+
None
89+
endpoints:
90+
None
91+
functions:
92+
buy-ticket: aws-ruby-step-functions-dev-buy-ticket
93+
reserve-parking-lot-space: aws-ruby-step-functions-dev-reserve-parking-lot-space
94+
return-ticket: aws-ruby-step-functions-dev-return-ticket
95+
release-parking-space: aws-ruby-step-functions-dev-release-parking-space
96+
check-weather: aws-ruby-step-functions-dev-check-weather
97+
layers:
98+
gem: arn:aws:lambda:YOUR_REGION:XXXXXXXXXXX:layer:aws-ruby-step-functions-dev-ruby-bundle:59
99+
```
100+
101+
## Usage
102+
103+
104+
After the deployment, go to the AWS Dashboard, and enter Step Functions page. You will see a newly created state machine.
105+
106+
Open the `organize-nice-weekend-state-machine` state machine and click on `Start Execution`. You need to provide the input in the JSON schema.
107+
108+
Example:
109+
110+
``` JSON
111+
{
112+
"first_name": "Daniel",
113+
"last_name": "Ani",
114+
"check_in_date": "2021-07-11T19:35:07+00:00",
115+
"check_out_date": "2021-07-11T19:35:07+00:00",
116+
"driver_plate": "RUBY"
117+
}
118+
```
119+
120+
![example-payload](./images/example_payload.png)
121+
122+
The `check_in_date` is the most important one. Without it, the state machine will be failed (it's needed for the purpose of the Wait state).
123+
124+
![wait-step-example](./images/wait-state.png)
125+
126+
127+
Later on, simply start the excecution.
128+
129+
You can watch live as the change between states takes place. It is also possible to view every parameter going in and out of each state.
130+
131+
The` weather` attribute is returned randomly (either `good` or `bad`), so sometimes you need several executions of the state machine to get a failed execution.
132+
133+
![output-data](./images/output-data.png)
134+
135+
To check created records check your DynamoDB tables (both for tickets, and parking lot spaces). In both cases, you will see that for failure executions, the `current_status` for records, will be changed to `canceled`.
136+
137+
Happy Path (good weather)
138+
139+
![happy-path](./images/happy-path.png)
140+
141+
Unhappy path (bad weather)
142+
143+
![unhappy-path](./images/unhappy-path.png)
144+
145+
146+
## Log retention
147+
148+
The log retention is setup for 30 days. To change it simply change the value of this attribute in `serverless.yml` file:
149+
150+
151+
``` bash
152+
logRetentionInDays: 30
153+
```
154+
155+
## Advanced configuration
156+
More options (like alerting in case of failed excecutions), could be found in the plugin [repository](https://github.com/serverless-operations/serverless-step-functions).
157+
158+
## Structure
159+
160+
| Path | Explanation |
161+
|----------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
162+
| `./src` | All code for the project. |
163+
| `./src/handlers/buy_ticket` | Lambda function for creating a ticket. |
164+
| `./src/handlers/return_ticket` | Lambda function for returning the ticket. |
165+
| `./src/handlers/reserve_parking_lot_space` | Lambda function for reserving the parking lot space. |
166+
| `./src/handlers/release_parking_space` | Lambda function for releasing the parking spaceticket. |
167+
| `./src/handlers/check_weather` | Lambda function for checking weather. |
168+
| `./src/common/` | Space for common, reusable pieces of code. |
169+
| `./src/common/adapters/dynamo_db_adapter.rb` | Adapter for communication with DynamoDB with the usage of AWS SDK for Ruby. Used for creating new records and updating existing ones. |
170+
| `./src/common/services/ticket_service.rb` | The service object pattern is widely used within ruby/rails developers. In our case used for all things related to tickets, so creating and updating records within DynamoDB. |
171+
| `./src/common/adapters/reserve_parking_service.rb` | In our case used for all things related to parking reservations, so creating and updating records within DynamoDB. |
172+
173+
## Serverless plugins
174+
175+
For this example, there are two serverless plugins used:
176+
177+
| Plugin | Explanation |
178+
|-----------------------|------------------------------------------------------------------------------------------------|
179+
| [serverless-ruby-layer](https://www.npmjs.com/package/serverless-ruby-layer) | For bundling ruby gems from `Gemfile` and deploys them to the lambda layer. |
180+
| [serverless-step-functions](https://www.npmjs.com/package/serverless-step-functions) | Serverless Framework plugin for AWS Step Functions. |
181+
182+
## Ruby gems
183+
184+
| Gem | Explanation |
185+
|--------------------|--------------------------------------------------------------------------------------------------------------------------------|
186+
| `aws-sdk-dynamodb` | It's a part of the AWS SDK for Ruby. Used for DynamoDB, in the case of this example - the creation of the new record. |
187+
188+
## Remove service
189+
190+
To remove the service do:
191+
192+
```bash
193+
sls remove
194+
```
195+
And the stack will be removed from the AWS.
135 KB
Loading
82.6 KB
Loading
60.4 KB
Loading
56.6 KB
Loading
253 KB
Loading
61.5 KB
Loading
83.3 KB
Loading

0 commit comments

Comments
 (0)