DVA

Step FunctionsのChoiceを使用した条件分岐

スポンサーリンク
Step Functions Choice Stateを使用した条件分岐 DVA
スポンサーリンク
スポンサーリンク

Step FunctionsのChoiceを使用した条件分岐

AWS DVAの出題範囲であるリファクタリングに関する内容です。

以下のページで、Step Functionsの基本的な事項について取り上げました。

上記のページでは、2つのステートで構成されたシンプルなステートマシンを構築しました。
今回は選択ステートを使用して、条件に応じて処理が分岐するステートマシンを構築することを目指します。

構築する環境

Diagram of Step Functions - Conditional branching using Choice State

Step Functionsステートマシン内に、3つのステートを定義します。

各ステートは、以下のLambda関数を実行するタスクとします。

  • Lambda関数1:現在日時情報からUNIX時間を計算し、これが偶数か奇数か判定する。
  • Lambda関数2:偶数であること旨の文字列を返す。
  • Lambda関数3:奇数であること旨の文字列を返す。

関数のランタイム環境はPython3.8とします。

最初のステートが完了後、選択ステートで次に実行するステートを分岐させます。
分岐の条件は、偶数/奇数の判定結果に応じて行います。
この値が偶数の判定だった場合は、Lambda関数2のステートが選ばれ、奇数の判定だった場合は、Lambda関数3のステートが選ばれます。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

awstut-dva/04/003 at main · awstut-an-r/awstut-dva
Contribute to awstut-an-r/awstut-dva development by creating an account on GitHub.

テンプレートファイルのポイント解説

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からステートマシンの作成状況を確認します。

Detail of Step Function 1.

正常にステートマシンが作成されていることがわかります。
ChoiceStateから分岐し、2つのステートのどちらかに進んだ後に終了する構成です。

動作確認

1回目

準備が整いましたので、ステートマシンの実行を行います。
AWS Management Consoleから実行する場合は、「Start execution」を押下します。

Detail of Step Function 2.

しばらく待機すると、ステートマシンの実行が正常に完了しました。
今回はChoiceStateからEventStateに移行しました。

Eventsの内容を確認します。

Detail of Step Function 3.

FirstStateで現在日時(2022/11/17 13:53:16)を取得し、これをUNIX時間に変換すると「1668693196」となります。
判定の結果、偶数ということで、「is_even」の値はtrueとなりました。

is_evenの値を踏まえて、ChoiceStateで条件分岐の判定が行われ、EvenStateが選択されたことがわかります。
最終的にEvenStateが実行され、「1668693196 is even !」が出力されました。

2回目

もう一度、ステートマシンを実行します。

Detail of Step Function 4.

ステートマシンの実行が正常に完了しました。
今回はChoiceStateからOddtStateに移行しました。

Eventsの内容を確認します。

Detail of Step Function 5.

FirstStateで現在日時(2022/11/17 14:03:33)を取得し、これをUNIX時間に変換すると「1668693813」となります。
判定の結果、奇数ということで、「is_even」の値はfalseとなりました。

is_evenの値を踏まえて、ChoiceStateで条件分岐の判定が行われ、OddStateが選択されたことがわかります。
最終的にOddStateが実行され、「1668693813 is odd !」が出力されました。

まとめ

Step Functionsの選択ステートを使用して、条件に応じて処理が分岐するステートマシンを構築しました。

タイトルとURLをコピーしました