AWS Step Functions を触ってみた

先日、Serverlessconf Tokyo 2017に参加して、いろいろなサーバーレスアーキテクチャの話を聞き、 AWS Step Functions を使って複数の AWS Lambda を管理しているという話がいろいろと便利そうだったので、触ってみた。
Step Functions を使うと、Lambda のアプリケーションを一連のステップとして視覚的に定義し、複数の Lambda をワークフローとして管理することができるとのこと。
さっそくやってみた。
ステップ 1: ステートマシンに名前を付ける
ダッシュボードの ステートマシンの作成
をクリック。
ステートマシンに名前を付ける。とりあえず、定番の Helloworld
で。
ステップ 2: 設計図を選択する
Lambda の結果による分岐ステップを試してみたかったので、 Choice ステート
を選択。
ステップ 3: コードとビジュアルワークフローを確認する
ものすごく簡単な Lambda をいくつか作ってみて、 コード
の部分にテンプレートとして準備されている JSON をベースに、ワークフローとして設定する。
下記の JSON を入力して、
{
"Comment": "test",
"StartAt": "hello",
"States": {
"hello": {
"Type": "Task",
"Resource": "arn:aws:lambda:ap-northeast-1:123456789012:function:hello",
"Next": "how are you"
},
"how are you": {
"Type": "Task",
"Resource": "arn:aws:lambda:ap-northeast-1:123456789012:function:how_are_you",
"Next": "ChoiceState"
},
"ChoiceState": {
"Type" : "Choice",
"Choices": [
{
"Variable": "$.response",
"StringEquals": "Great",
"Next": "response_good"
},
{
"Variable": "$.response",
"StringEquals": "Not so good",
"Next": "response_bad"
}
],
"Default": "DefaultState"
},
"response_good": {
"Type" : "Task",
"Resource": "arn:aws:lambda:ap-northeast-1:123456789012:function:response_good",
"Next": "bye"
},
"response_bad": {
"Type" : "Task",
"Resource": "arn:aws:lambda:ap-northeast-1:123456789012:function:response_bad",
"Next": "bye"
},
"DefaultState": {
"Type": "Fail",
"Error": "DefaultStateError",
"Cause": "No Matches!"
},
"bye": {
"Type": "Task",
"Resource": "arn:aws:lambda:ap-northeast-1:123456789012:function:bye",
"End": true
}
}
}
ビジュアルワークフロー
の右側にあるリロードアイコンをクリックして、 グラフのプレビューを更新すると、
ちゃんと反映された。
ちなみに、作った Lambda は下記のとおり。
【hello.py】
event
の name
を受け取り、 hello, <name>
と表示して、そのまま name
を返す。
# hello.py
def lambda_handler(event, context):
print "hello, %s" % event[u'name']
return {u'name': event[u'name']}
【how_are_you.py】
event
の name
を受け取って、 Bob
だったら、 name
と、 response
として Great
を返す。event
の name
を受け取って、 Bob
以外だったら、 name
と、 response
として Not so good
を返す。
# how_are_you.py
def lambda_handler(event, context):
if event[u'name'] == 'Bob':
return {u'name': event[u'name'], u'response': u'Great'}
else:
return {u'name': event[u'name'], u'response': u'Not so good'}
【response_good.py】 【response_bad.py】 【bye.py】
それぞれ、固定の文字列を返すだけ。
# response_good.py
def lambda_handler(event, context):
return 'Good!'
# response_bad.py
def lambda_handler(event, context):
return "What's wrong?"
# bye.py
def lambda_handler(event, context):
return 'Bye!'
ステートマシンの作成
をクリックすると、 ステートマシン実行の IAM ロール
を指定するダイアログが出てくるので、指定して OK
をクリックする。
(ロールがない場合はここで作成)
これだけで、ワークフローが作れてしまった。
コードのポイント
コード
の部分に入力するJSONは、 JSON ベースの Amazon ステートメント言語 (ASL) で記述する。
Type
Type
として設定できるのは、 Pass
Task
Choice
Wait
Succeed
Fail
Parallel
があり、
フィールドとしては上記の表のとおり、設定ができる。
今回は主に、 Task
と Choice
を使用した。
Task
Task
には、 Next
もしくは "End": true
が必要で、 Next
で指定した文字列のタスクが次に実行される。Resource
には、 Lambda の ARN などを指定する。
"hello": {
"Type": "Task",
"Resource": "arn:aws:lambda:ap-northeast-1:123456789012:function:hello",
"Next": "how are you"
},
ChoiceState
ChoiceState
としては、 StringEquals
や BooleanEquals
や TimestampGreaterThan
などの条件を設定できる。
今回の JSON の ChoiceState
の部分では、 Variable
で $.response
を見て、 StringEquals
で指定した文字列と一致するかの判別をしている。
"ChoiceState": {
"Type" : "Choice",
"Choices": [
{
"Variable": "$.response",
"StringEquals": "Great",
"Next": "response_good"
},
{
"Variable": "$.response",
"StringEquals": "Not so good",
"Next": "response_bad"
}
],
"Default": "DefaultState"
},
Variable
として、 $
で結果を受け取ることができる。
例えば、JSON が下記のようなもので結果として渡ってきたら、
{
"foo": 123,
"bar": ["a", "b", "c"],
"car": {
"cdr": true
}
}
下記のような形で、値が取得できる。
$.foo => 123
$.bar => ["a", "b", "c"]
$.car.cdr => true
実際に実行してみる
新しい実行
をクリックして、 実行 ID
に Bob
を入れ、 event
として下記のように設定して、 実行の開始
をクリック。
{
"name": "Bob"
}
無事、実行された。Bob
なので、 response_good
の方が実行されているのが分かる。
今度は、 name
に Tom
を入れて実行してみたら、想定どおり response_bad
の方が実行され、ちゃんと分岐処理が実行されていることが確認できた。
料金
AWS Step Functions の料金としては、アプリケーションワークフローのあるステップから次のステップに移行すると、状態間を遷移したことになり、 各状態遷移に対して料金が発生する。
毎月 4,000 回までの状態遷移は無料で、それ以降は、状態遷移 1,000 回あたり 0.025 USD (状態遷移 1 回あたり 0.000025 USD)となっている。
【参考】
料金 - AWS Step Functions | AWS
まとめ
今回 AWS Step Functions を初めて触ってみたが、比較的簡単にワークフローが作れて、Lambda が管理できることがわかった。
Lambda の制限として、実行時間が5分までというものがあるので、細かい機能で複数の Lambda に分割するケースがよくあると思う。そういった場合に、 AWS Step Functions をうまく活用してやれば管理が楽になりそうなので、社内でも積極的に使っていきたい。