2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AWS Step Functions 入門してみた

Last updated at Posted at 2021-12-19

初めに

Step Functions に入門してみました。操作方法などを簡単に書いておきます。

ステートマシンの作成・実行

ステートマシンのコードには ASL(Amazon States Laguage)という独自の言語が使われます。

簡単に作成してみます。以下のステートマシンは、一つのステートを実行するステートマシンです。

image.png

{
  "StartAt": "State",
  "States": {
    "State": {
      "Type": "Pass",
      "Result": "State Result",
      "End": true
    }
  }
}

これを実行してみます。実行前に以下の画面が表示されます。

image.png

「実行の開始」を押すと以下の画面が表示されます。

image.png

これでこのステートマシンの実行が完了しました。上図の左側の「State」をクリックした後、右側の「ステップ入力」をクリックすると、この「State」が入力に何を受け取ったかが表示されます。

image.png

続けて出力も見てみます。

image.png

このステートマシンは、実行が開始されると、

{
  "Comment": "Insert your JSON here"
}

を受け取り、

"State Result"

を返すことがわかりました。

入力・出力の変更

入力の値を変更するには、ステートマシンを実行する前の画面において編集します。

image.png

こちらを以下のように編集します。

image.png

次に出力の値を変更します。出力の値を変更するには、以下のようにステートマシンの Result フィールドを変更します。

{
  "StartAt": "State",
  "States": {
    "State": {
      "Type": "Pass",
      "Result": "Blue",
      "End": true
    }
  }
}

これでこのステートマシンは、

{
  "Color": "Red"
}

を受け取り、

"Blue"

を返すステートマシンになりました。

入力に受け取った値を出力する

受け取った値を出力に反映させるには、InputPath フィールドを追加し、そこに入力のキーを指定します。

{
  "StartAt": "State",
  "States": {
    "State": {
      "Type": "Pass",
      "InputPath": "$.Color",
      "End": true
    }
  }
}

入力は前回と同じですが、出力が入力の値を反映したものになりました。

image.png

次に JSON 形式で受け取った値を返す方法ですが、これには ResultPath フィールドを追加します。

{
  "StartAt": "State",
  "States": {
    "State": {
      "Type": "Pass",
      "InputPath": "$.Color",
      "ResultPath": "$.Color",
      "End": true
    }
  }
}

この出力結果は以下のようになります。

image.png

入力と出力が一致しています。実はこのように入力をそのまま出力に渡すようにするには、InputPathResultPath は必要ありません。つまり以下のコードで十分です。

{
  "StartAt": "State",
  "States": {
    "State": {
      "Type": "Pass",
      "End": true
    }
  }
}

出力を制限する

以下のような入力を考えます。

{
  "ID": "A10",
  "ProductName": "Jacket",
  "Color": "Red"
}

これを受けて、ID と赤色のジャケットの在庫の個数を返すステートを作成します。そのためには以下のように、OutputPath で出力するキーを指定します。

{
  "StartAt": "State",
  "States": {
    "State": {
      "Type": "Pass",
      "Result": 3,
      "ResultPath": "$.Stock",
      "OutputPath": "$['ID', 'Stock']",
      "End": true
    }
  }
}

実行結果は以下のようになります。

image.png

"ResultPath": "$.Stock" により、出力に Stock というキーを追加しています。OutputPath フィールドで、出力するキーを制御できます。ここでは、入力の ID キー と、追加した Stock キーを出力し、それ以外のキーは出力しないように制御しています。

Task ステート

ステートマシンから他の AWS リソースを実行するには、タスクステートを使用します。ステートにはいくつか種類があり、ステートの Type フィールドで指定します。例えば、

  • "Type": "Pass":パスステート
  • "Type": "Task":タスクステート

があります。

詳細はこちらです。

まずは 注文を受けて、在庫数を返す Lambda 関数を作成します。

lambda_function.py
import json

def lambda_handler(event, context):
    product_name = event['ProductName']
    color = event['Color']
    product_table = {
        'Jacket': {
            'Red': 3,
            'Blue': 5
        }
    }
    return product_table[product_name][color]

その後 Lambda 関数のリソースベースのポリシーに、ステートマシンのロールの ARN を指定し、lambda:InvokeFunction を許可します。

1.png

これで呼び出す Lambda 関数の作成は完了です。

続いて、ステートマシンを作成します。パスステートと違う点は、以下の 4 点です。

  • Type フィールドを Task に変更
  • Resource フィールドで呼び出す Lambda 関数の ARN を指定
  • Parameters フィールドで Lambda 関数に渡すパラメータを追加
  • Result フィールドを削除
{
  "StartAt": "State",
  "States": {
    "State": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:123456789012:function:GetStoreFunction",
      "Parameters": {
        "ProductName.$": "$.ProductName",
        "Color.$": "$.Color"
      },
      "ResultPath": "$.Stock",
      "OutputPath": "$['ID', 'Stock']",
      "End": true
    }
  }
}

この実行結果は以下のようになります。

image.png

Choice ステート

最後にステートの出力結果によって次の処理を分岐させる Choice ステートについて書きます。前回の Lambda 関数は、商品の在庫数を返します。その在庫数によって出力にコメントを含めるように新しいステートを作成してみます。

まずは在庫数が 5 以上であるかどうかを判定する Choice ステートを新たに追加します。

    "State2": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.Stock",
          "NumericGreaterThanEquals": 5,
          "Next": "Sufficient"
        }
      ],
      "Default": "Shortage"
    }

Variable フィールドは、 Choice ステートが受け取る入力中のどのキーの値を評価するかについて指定します。ここでは $.Stock と指定していますので、商品の在庫数を評価することになります。

"NumericGreaterThanEquals": 5 については、受け取った商品の在庫数が 5 個以上であれば "Next" フィールドに記載されているステートに進みます。そうでなければ次の条件に進みます。Default フィールドはどの条件にも合致しない場合に進むステートを定義します。プログラムではいわゆる else 文に相当します。

次に Sufficient ステートと Shortage ステートを記述します。それぞれ新たに出力するキーを追加しています。End フィールドはこのステートでステートマシンが終了する場合に追加します。

    "Sufficient": {
      "Type": "Pass",
      "Result": "Sufficient stock",
      "ResultPath": "$.comment",
      "End": true
    }
    "Shortage": {
      "Type": "Pass",
      "Result": "Shortage stock",
      "ResultPath": "$.comment",
      "End": true
    }

ステートマシン全体のコードは以下のようになります。最初の Lambda 関数を呼び出す State1 は、State2 に処理が続くため、Next フィールドを追加しています。

{
  "StartAt": "State1",
  "States": {
    "State1": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:123456789012:function:GetStoreFunction",
      "Parameters": {
        "ProductName.$": "$.ProductName",
        "Color.$": "$.Color"
      },
      "ResultPath": "$.Stock",
      "OutputPath": "$['ID', 'Stock']",
      "Next": "State2"
    },
    "State2": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.Stock",
          "NumericGreaterThanEquals": 5,
          "Next": "Sufficient"
        }
      ],
      "Default": "Shortage"
    },
    "Sufficient": {
      "Type": "Pass",
      "Result": "Sufficient stock",
      "ResultPath": "$.comment",
      "End": true
    },
    "Shortage": {
      "Type": "Pass",
      "Result": "Shortage stock",
      "ResultPath": "$.comment",
      "End": true
    }
  }
}

image.png

それぞれの分岐を通るように入力を与えてみます。

以下は在庫数が 5 の商品の入力になります。

image.png

上記の入力に対する実行結果は以下のようになります。

image.png

以下は在庫数が 3 の商品の入力になります。

image.png

上記の入力に対する実行結果は以下のようになります。

image.png

参考記事

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?