Step FunctionsのChoiceを使用した条件分岐
AWS DVAの出題範囲であるリファクタリングに関する内容です。
以下のページで、Step Functionsの基本的な事項について取り上げました。
上記のページでは、2つのステートで構成されたシンプルなステートマシンを構築しました。
今回は選択ステートを使用して、条件に応じて処理が分岐するステートマシンを構築することを目指します。
構築する環境
Step Functionsステートマシン内に、3つのステートを定義します。
各ステートは、以下のLambda関数を実行するタスクとします。
- Lambda関数1:現在日時情報からUNIX時間を計算し、これが偶数か奇数か判定する。
- Lambda関数2:偶数であること旨の文字列を返す。
- Lambda関数3:奇数であること旨の文字列を返す。
関数のランタイム環境はPython3.8とします。
最初のステートが完了後、選択ステートで次に実行するステートを分岐させます。
分岐の条件は、偶数/奇数の判定結果に応じて行います。
この値が偶数の判定だった場合は、Lambda関数2のステートが選ばれ、奇数の判定だった場合は、Lambda関数3のステートが選ばれます。
CloudFormationテンプレートファイル
上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。
https://github.com/awstut-an-r/awstut-dva/tree/main/04/003
テンプレートファイルのポイント解説
Lambda関数
関数1
Resources:
Function1:
Type: AWS::Lambda::Function
Properties:
Code:
ZipFile: |
import datetime
import time
def lambda_handler(event, context):
now = datetime.datetime.now()
epoch_time = int(time.mktime(now.timetuple()))
return {
'now': now.strftime('%Y%m%d%H%M%S%f'),
'epoch_time': {
'value': epoch_time,
'is_even': (not bool(epoch_time % 2))
}
}
FunctionName: !Sub "${Prefix}-function-01"
Handler: !Ref Handler
Runtime: !Ref Runtime
Role: !GetAtt FunctionRole.Arn
Code language: YAML (yaml)
Step Functionsで実行する上で、特別な設定は不要です。
実行するコードに注目します。
現在日時を取得し、これをUNIX時間に変換します。
このUNIX時間の数値を2で割った時の余りを求め、これから偶数/奇数を判定します。
return文で辞書型オブジェクトを返します。
例えば以下のようなオブジェクトとなります。
{
"now": "20221117135316055513",
"epoch_time": {
"value": 1668693196,
"is_even": True
}
}
Code language: JSON / JSON with Comments (json)
関数2
Lambdaそのものは関数1と同様です。
実行するコードに注目します。
import datetime
import time
def lambda_handler(event, context):
return '{epoch_time} is even !'.format(
epoch_time=event['epoch_time']['value'])
Code language: YAML (yaml)
偶数である旨の文字列を返します。
文字列を作成するために、eventオブジェクトを参照します。
このeventは、関数1で生成される辞書型オブジェクトと同様の構造を持っているものとします。
関数3
import datetime
import time
def lambda_handler(event, context):
return '{epoch_time} is even !'.format(
epoch_time=event['epoch_time']['value'])
Code language: YAML (yaml)
こちらも実行するコードに注目します。
内容は関数2とほとんど同様です。
eventオブジェクトを参照し、奇数である旨の文字列を返します。
Step Functions
Resources:
StateMachine:
Type: AWS::StepFunctions::StateMachine
Properties:
Definition:
Comment: !Sub "${Prefix}-StateMachine"
StartAt: FirstState
States:
FirstState:
Type: Task
Resource: !Ref FunctionArn1
Next: ChoiceState
ChoiceState:
Type: Choice
Choices:
- Variable: $.epoch_time.is_even
BooleanEquals: true
Next: EvenState
- Variable: $.epoch_time.is_even
BooleanEquals: false
Next: OddState
EvenState:
Type: Task
Resource: !Ref FunctionArn2
End: true
OddState:
Type: Task
Resource: !Ref FunctionArn3
End: true
LoggingConfiguration:
Destinations:
- CloudWatchLogsLogGroup:
LogGroupArn: !GetAtt LogGroup.Arn
IncludeExecutionData: true
Level: ALL
RoleArn: !GetAtt StateMachineRole.Arn
StateMachineName: !Ref Prefix
StateMachineType: STANDARD
Code language: YAML (yaml)
ステートマシン全体の構造を確認します。
StartAtプロパティを見ると、FirstStateから処理が開始されることがわかります。
FirstStateでは、関数1を実行します。
その後ChoiceStateに移行し、FirstStateから返ってきた値を参照して、条件分岐の判定が行われます。
「$.epoch_time.is_even」のような記法で参照先を指定することができます。
今回は組み込み関数BooleanEqualsを使用して、真理値を判定します。
この値がtrueの場合、EventStateに移行し、falseの場合はOddStateに移行します。
EventState・OddStateでは、それぞれ関数2・関数3を実行します。
各ステートの終了後、ステートマシン全体の処理が完了となります。
環境構築
CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。
CloudFormationスタックを作成し、スタック内のリソースを確認する
CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- Step Functionsのステートマシン:dva-04-003
- Lambda関数1:dva-04-003-function-01
- Lambda関数2:dva-04-003-function-02
- Lambda関数3:dva-04-003-function-03
AWS Management Consoleからステートマシンの作成状況を確認します。
正常にステートマシンが作成されていることがわかります。
ChoiceStateから分岐し、2つのステートのどちらかに進んだ後に終了する構成です。
動作確認
1回目
準備が整いましたので、ステートマシンの実行を行います。
AWS Management Consoleから実行する場合は、「Start execution」を押下します。
しばらく待機すると、ステートマシンの実行が正常に完了しました。
今回はChoiceStateからEventStateに移行しました。
Eventsの内容を確認します。
FirstStateで現在日時(2022/11/17 13:53:16)を取得し、これをUNIX時間に変換すると「1668693196」となります。
判定の結果、偶数ということで、「is_even」の値はtrueとなりました。
is_evenの値を踏まえて、ChoiceStateで条件分岐の判定が行われ、EvenStateが選択されたことがわかります。
最終的にEvenStateが実行され、「1668693196 is even !」が出力されました。
2回目
もう一度、ステートマシンを実行します。
ステートマシンの実行が正常に完了しました。
今回はChoiceStateからOddtStateに移行しました。
Eventsの内容を確認します。
FirstStateで現在日時(2022/11/17 14:03:33)を取得し、これをUNIX時間に変換すると「1668693813」となります。
判定の結果、奇数ということで、「is_even」の値はfalseとなりました。
is_evenの値を踏まえて、ChoiceStateで条件分岐の判定が行われ、OddStateが選択されたことがわかります。
最終的にOddStateが実行され、「1668693813 is odd !」が出力されました。
まとめ
Step Functionsの選択ステートを使用して、条件に応じて処理が分岐するステートマシンを構築しました。