🤖

SAMを使って超簡単にStep Functionsを動かしてみる

2024/10/15に公開

Step Functions is 何?

Step Functions は、デベロッパーが AWS のサービスを利用して分散型アプリケーションを構築し、プロセスを自動化するとともに、マイクロサービスをオーケストレーションして、データと機械学習 (ML) のパイプラインを作成できるようにするビジュアルワークフローサービスです。

https://aws.amazon.com/jp/step-functions/

これを利用することで、視覚的に様々なサービスを組み合わせて利用することができるようです!

早速触ってみよう

構成

今回はAPIとしてステートマシンを実行し、簡単なLambdaを2つ順番に実行させるようにしてみます。

フォルダ構成は以下のようになっています

├─test-lambda1
├─test-lambda2
├─statemachine
│         └─ define.json
├─samconfig.toml
├─template.yaml

test-lambda1|2は、何でもよいですが、私はログを出力するだけのLambdaにしました。

ステートマシンを定義する方法として、template.yamlに直接記述する方法と、定義用のファイルを作成する方法の2種類あります。
今回はstatemachine/define.jsonというファイルを作成して、ステートマシンを定義していこうと思います。

define.jsonを作成

名前はなんでもいいですが、今回はdefine.jsonとしました。
これらはJSONをベースとしたASL(Amazon States Language)という言語で記述されます。
詳しい記載方法についてはまた別の機会にするとして、今回は以下のように作成しました。

{
  "StartAt": "test-lambda1",
  "States": {
    "test-lambda1": {
      "Type": "Task",
      "Resource": "${Function1}",
      "Next": "test-lambda2"
    },
    "test-lambda2": {
      "Type": "Task",
      "Resource": "${Function2}",
      "End": true
    }
  }
}

StartAt: 開始するStateを記載します。
States: Stateの定義。Taskとして、それぞれのLambdaを指定。
"End": true: ステートマシンの終了。

つまり、

  1. ステートマシン開始
  2. test-lambda1を実行
  3. test-lambda2を実行
  4. ステートマシン終了

というのをJSONで定義しました。

VSCodeの拡張機能で、https://marketplace.visualstudio.com/items?itemName=paulshestakov.aws-step-functions-constructor をインストールすると、以下のように視覚化してくれて便利です✌

template.yamlを作成

ではステートマシン等をtemplate.yamlに定義していきましょう。
今回は以下のように作成しました。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  step functions test
  
Globals:
  Function:
    Timeout: 10

Resources:
  TestFunction1:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-TestFunction1"
      CodeUri: test-lambda1/function/
      Handler: app.lambdaHandler
      Runtime: nodejs20.x
      Architectures:
        - x86_64
  TestFunction2:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub "${AWS::StackName}-TestFunction2"
      CodeUri: test-lambda2/function/
      Handler: app.lambdaHandler
      Runtime: nodejs20.x
      Architectures:
        - x86_64
  SimpleStateMachine:
    Type: AWS::Serverless::StateMachine
    Properties:
      DefinitionUri: statemachine/define.json
      DefinitionSubstitutions:
        Function1: !GetAtt TestFunction1.Arn
        Function2: !GetAtt TestFunction2.Arn
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /statemachine
            Method: get

Outputs:
  StepFunctionApi:
    Description: "API Gateway endpoint URL for Prod stage for step function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/statemachine/"

SimpleStateMachineとして定義しているのが、今回作成するステートマシンです。
DefinitionUriと、DefinitionSubstitutionsについて解説していきます。

DefinitionUri

ASLのファイルパスを指定します。

DefinitionSubstitutions

ASLへパラメータを渡します。今回、ASLで以下のように記載しました。

"Resource": "${Function1}"

${Function1}に対して、template.yamlからTestFunction1のARNをパラメータとして渡しています。

ビルド&デプロイして実行

sam build --use-container && sam deploy
Key                 StepFunctionApi
Description         API Gateway endpoint URL for Prod stage for step function
Value               https://xxxxxxxxxx.execute-api.amazonaws.com/Prod/statemachine/

デプロイ時に上記のようにAPIのURLが表示されるはずなので、そちらからステートマシンを実行してみましょう。

今回は2つのLambdaを順番に呼び出しているだけなので、私はCloudWatchでそれぞれがログが出力されていることを確認しました。

まとめ

今回はStep Functionsを用いて、異なる2つのLambdaを順次実行させてみました。
LambdaからLambdaを実行する場合、SQSをトリガーとしてLambdaを実行させるケースもあると思いますが、Step Functionsを用いればLambdaのソース外で実行プロセスを定義できるので、とても柔軟性が高くなりそうだと思いました!

Lambdaの実行結果で遷移を分岐する、なんてこともできるはずなので、今度はそのあたりも触っていこうと思います。

参考

https://dev.classmethod.jp/articles/aws-sam-step-functions/

Discussion