この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
このブログでは、AWS Step Functionsを使用して、複数のAWS Lambda関数を統合するサーバーレスワークフローを設計し、実行する方法について紹介します。
はじめに
AWS Step Functions は、デベロッパーが分散アプリケーションの構築、IT およびビジネスプロセスの自動化、AWS のサービスを利用したデータと機械学習のパイプラインの構築に使用するローコードのビジュアルワークフローサービスです。ワークフローは、障害、再試行、並列化、サービス統合、可観測性などを管理するため、デベロッパーはより価値の高いビジネスロジックに集中することができます。
最近、次の記事でAWS Step Functionsについて学びました。
- https://aws.amazon.com/jp/step-functions/?nc1=h_ls&step-functions.sort-by=item.additionalFields.postDateTime&step-functions.sort-order=desc
- https://aws.amazon.com/jp/getting-started/hands-on/create-a-serverless-workflow-step-functions-lambda/?nc1=h_ls
- https://lumigo.io/aws-serverless-ecosystem/aws-step-functions-limits-use-cases-best-practices/
Step Functionsとは
AWS Step Functionsは、サーバーレスオーケストレーションです。ロジックを使用して、アプリケーションのワークフローを個別に設計し、管理できます。
- Step Functionsを使用すると、アプリケーション開発がより速く、より直感的になります。
- 複数のLambda関数を、簡単にデバッグと変更ができる柔軟なワークフローに容易に統合できます。 ステップ関数は、追加のロジックを必要とせずに、アプリケーションの各ステップを簡単にトリガーおよび追跡できます。
- Step Functionsコンソールは、アプリケーションロジックの視覚化に役立つ、ステートマシンのグラフィック表現を提供します。
-
Step Functionsを使用して作成するワークフローはステートマシン(State Machine)と呼ばれ、ワークフローの各ステップはステート(States)と呼ばれます。
Step Functionsのしくみ
- Workflow Studioでビジュアルワークフローを定義します。コンソールがコードを自動生成します。コンソールでコードスニペットを使用して自分でコーディングすることも、VSCodeを使用してローカルでコーディングすることもできます。
- ワークフローでトリガーするリソースを指定します。
- 実行を開始して、ワークフローのステップが意図したとおりに動作していることを確認します。コンソールから直接実行履歴を検査し、デバッグします。
Lambda関数を使用したStep Functions
飲み物を注文するアプリケーションのワークフローを例に挙げたいと思います。AWS Lambdaコンソールを開き、[関数の作成]をクリックします。下図の設定内容を設定し、Lambda関数を作成します。同様に他のLambda関数(Coffee_Function、Juice_Function)も作成します。ワークフローの名前は「DrinksOrderApplication」です。まず、ワークフローを視覚化します。3つのLambda関数と、Choice stateとFallback stateで構成します。
- Order – 注文の詳細を入力値として送信するタスクです。
- Drinks – 次のステップ(コーヒーまたはジュース)を選択するための入力値として注文の詳細を使用するのは、Choice Stateです。
- Coffee – Lambda関数によって実装されるタスクです。
- Juice – Lambda関数によって実装されるタスクです。
- Fallback - States.Runtimeエラーをキャッチします。
ステップ 1 : ステートマシンとサーバーレスワークフローを作成する
AWS Step Functionsコンソールを開きます。[ステートマシンを作成する]をクリックし、「コードでワークフローを記述」を選択します。 「次へ」をクリックします。
「ステートマシン名」に「OrderStateMachine」と入力します。
[既存のロールを選択する]を選択し、Lamdaを実行できる役割をドロップダウンから選択します。
新しいIAMロールを作成することもできます。この手順に従って、新しいIAMロールを作成します。
- Identity and Access Management(IAM)コンソールに移動します。
- [ロールを作成]をクリックし、信頼されたエンティティタイプからAWSサービスを選択し、ユースケースからLambdaを指定し、[次へ]をクリックします。
- [ポリシーの作成]をクリックします。
- 下図のように詳細を設定します。
- [次のステップ:タグ]を選択します。
- [次のステップ:確認]を選択し、ポリシー名を入力し、[ポリシーの作成]をクリックします。
ステップ 2 : Lambda関数を作成する
ステートマシンを作成したので、ワークフローを設計できます。このタスクでは、ステートマシン用に3つのLambda関数を作成する必要があります。AWS Lambdaコンソールを開き、[関数の作成]をクリックします。 下図の設定内容を設定し、Lambda関数を作成します。
同様に他のLambda関数(Coffee_Function、Juice_Function)も作成します。
OrderLambdaFunction
これは、注文の詳細を入力として受け取り、注文情報を処理するLambda関数です。
import json
def lambda_handler(event, context):
Order = {
"OrderType" : "Drinks",
"DrinksCategory" : event['DrinksCategory'],
"DrinksType" : event['DrinksType']
}
return Order
Coffee_Function
Drink_StateはChoice_Stateです。 Drink Category がコーヒーの場合、Coffee_FunctionのLambda関数が呼び出されます。 コーヒーの注文内容に応じて、金額の情報を返します。
import json
def lambda_handler(event, context):
OrderType = event['OrderType']
DrinksCategory = event['DrinksCategory']
DrinksType = event['DrinksType']
Price = getPrice(OrderType, DrinksCategory, DrinksType)
print("Price : ", Price)
return {
'OrderType' : OrderType,
'DrinksCategory': DrinksCategory,
'DrinkType': DrinksType,
'Price': Price
}
def getPrice(OrderType, DrinksCategory, DrinksType):
print(OrderType, " ", DrinksCategory, " " , DrinksType)
if (OrderType == "Drinks" and DrinksCategory == "Coffee" and str(DrinksType) == "Cappuccino"):
return "¥300"
elif (OrderType == "Drinks" and DrinksCategory == "Coffee" and str(DrinksType) == "Espresso"):
return "¥500"
else:
return "This drink is not available!"
Juice_Function
Drink Category がジュースの場合、Juice_FunctionのLambda関数が呼び出されます。ジュースの注文内容に応じて、金額の情報を返します。
import json
def lambda_handler(event, context):
OrderType = event['OrderType']
DrinksCategory = event['DrinksCategory']
DrinksType = event['DrinksType']
Price = getPrice(OrderType, DrinksCategory, DrinksType)
print("Price : ", Price)
return {
'OrderType' : OrderType,
'DrinksCategory': DrinksCategory,
'DrinksType': DrinksType,
'Price': Price
}
def getPrice(OrderType, DrinksCategory, DrinksType):
print(OrderType, " ", DrinksCategory, " " , DrinksType)
if (OrderType == "Drinks" and DrinksCategory == "Juice" and str(DrinksType) == "Orange"):
return "¥300"
elif (OrderType == "Drinks" and DrinksCategory == "Juice" and str(DrinksType) == "Strawberry"):
return "¥500"
else:
return "This drink is not available!"
ステップ 3 : ステートマシン定義の書き込み
AWS Step Functionsコンソールを開きます。編集をクリックします。ステートマシン定義ウィンドウの内容を「OderStateMachine」定義に置き換えます。
ワークフローの定義
{
"Comment": "Order Process State Machine",
"StartAt": "Order",
"States": {
"Order": {
"Type": "Task",
"Resource": "arn:aws:lambda:XXXX:function:orderfunction",
"Next": "Drinks"
},
"Drinks": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.DrinksCategory",
"StringEquals": "Coffee",
"Next": "Coffee"
},
{
"Variable": "$.DrinksCategory",
"StringEquals": "Juice",
"Next": "Juice"
}
]
},
"Coffee": {
"Type": "Task",
"Resource": "arn:aws:lambda:XXXX:function:coffee_function",
"Catch": [
{
"ErrorEquals": [
"States.TaskFailed"
],
"Next": "fallback"
}
],
"End": true
},
"Juice": {
"Type": "Task",
"Resource": "arn:aws:lambda:XXXX:function:juice_function",
"Catch": [
{
"ErrorEquals": [
"States.TaskFailed"
],
"Next": "fallback"
}
],
"End": true
},
"fallback": {
"Type": "Pass",
"Result": "Hello, AWS Step Functions!",
"End": true
}
}
}
ワークフローの視覚化
ステップ 4 : ステートマシンをテストする
ワークフローのステップが期待通りに動作することを確認します。「新しい実行」を選択し、「入力」にJSONで入力値を指定し、「実行の開始」をクリックします。
コンソールのグラフインスペクターに、現在のステータスが表示されます。ワークフロー図で各ステップをクリックすると、ステップに関する情報(詳細・ステップ入力・ステップ出力)を確認できます。
実行イベント履歴から、実行履歴のログと各ステップのステータスを確認できます。CloudWatchログを確認することもできます。
まとめ
このブログでは、インプットに応じて異なるLambda関数を呼び出すOrderStepFunctionワークフローを作成し、AWS Step Functionsの基本についてご紹介しました。AWS Step Functionsを使用すると、ワークフローをステートマシンとして定義し、複雑なコードをわかりやすいステートメントとダイアグラムに変換できます。これにより、マルチステップシステムの構築が簡単になります。
このブログがお役に立てば幸いです。Step Functionsを使用してみてください。