【AWS DVA学習】AWS Step Functionsのチュートリアルをやってみた

# はじめに

AWS DVA取得のためのアウトプットが目的です。

# 対象チュートリアル

公式ドキュメントの`Lambdaを使用するStep Functionsステートメントマシンの作成`。

https://docs.aws.amazon.com/step-functions/latest/dg/tutorials.html

# やってみた

## LambdaのIAMロールを作成

Lambdaに割り当てるためのIAMロールを作成します。

![スクリーンショット 2021-07-18 18.37.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/6a07c6bd-8ef0-c296-0f1f-3056b3b0811a.png)

ポリシーは`AWSLambdaBasicExecutionRole`を選択します。

![スクリーンショット 2021-07-18 18.37.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/82a26e0b-95a4-a9d5-ca6d-5a42fc6f97a4.png)

以降は特に何もせずにロールを作成します。

## Lambdaを作成

関数名：`HelloFunction`
ランタイム：`Node.js 12.x`
デフォルトの実行ロールの変更：`既存のIAMロールを使用する`

![スクリーンショット 2021-07-18 18.45.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/47fbcd7e-7ac1-efbf-aaad-a040f67593bd.png)

Lambdaのコードを以下のチュートリアル提供コードに置換してDeploy。

```
exports.handler = (event, context, callback) => {
    callback(null, "Hello, " + event.who + "!");
};
```

![スクリーンショット 2021-07-18 18.46.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/c06f53c2-137d-5e1f-577a-7e0bded6b381.png)

後で使用するので、LambdaのARNをメモします。

ちなみに、この時点でLambdaの実行ログが記録されるCloudWatch Logsロググループは作成されていませんが、Lambdaが実行されると自動で作成されます（LambdaのIAMロールに権限が付与されていれば）。

## Lambdaのテスト

以下のサンプルデータのテストイベントを作成します。

```
{
    "who": "AWS Step Functions"
}
```

![スクリーンショット 2021-07-18 19.00.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/4d02e814-fff8-290b-a653-57e09bb822be.png)

テストを実行し、実行結果のHelloの後にサンプルデータ`who`のバリューが表示されていることを確認します。

![スクリーンショット 2021-07-18 19.02.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/d546d82e-053f-efd2-0ab9-67030fdd1c13.png)

## Step Functionsでステートマシンを作成

ステートマシンの作成を選択。

![スクリーンショット 2021-07-18 19.04.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/8d976052-31b5-dea4-2128-29c5567b9055.png)

`コードでワークフローを記述`、標準を選択。

![スクリーンショット 2021-07-18 19.09.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/ee6de345-fa18-cf61-e736-3ff8b0cc7196.png)

標準かExpressかは、ユースケースで異なります。

Expressは大量イベント処理ワークロードに最適で、最大5分間実行でき、各ワークフローステップの、`少なくとも1回`の実行を保証します。

対して標準は最大1年間実行でき、監査可能なワークフローに最適です。各ワークフローステップの実行を1回だけ保証するので、2回処理するのが許されないクレジットカードの請求のワークフローがユースケースにあたります。

それぞれのワークフローでサポートしているオプションが異なる上、作成後の変更ができないので、注意が必要です。

https://docs.aws.amazon.com/step-functions/latest/dg/concepts-standard-vs-express.html

https://aws.amazon.com/step-functions/faqs/?nc1=h_ls

> Q：エクスプレスワークフローと標準ワークフローはいつ使用する必要がありますか？

>イベント率が高く、期間が短いワークロードには、エクスプレスワークフローを使用する必要があります。Expressワークフローは、1秒あたり100,000を超えるイベントレートをサポートします。Expressワークフローの最大期間は5分です。Expressワークフローは、各ワークフローステップの「少なくとも1回」の実行を保証します。失敗したワークフローは最初から再実行する必要があります。Expressワークフローは、すべてのサービス統合をサポートします。Expressワークフローは、アクティビティ、ジョブ実行（.sync）、およびコールバックパターンをサポートしていません。

>AWS Step Functionsの標準ワークフローは、ワークフローステップの繰り返しに費用がかかる（たとえば、長時間実行されるメディアトランスコードの再起動）または有害である（たとえば、クレジットカードに2回請求する）、長時間実行され、耐久性があり、監査可能なワークフローに適しています。ワークロードの例には、機械学習モデルのトレーニングと展開、レポートの生成、請求、クレジットカード処理、注文と履行のプロセスが含まれます。標準ワークフローは、各ワークフローステップの実行を1回だけ保証し、最大期間は1年です。これらのワークフローは、ワークフローの実行中および実行後に検査できる各ワークフローに関する詳細なステップバイステップの情報を追跡および保存します。標準ワークフローは、すべてのサービス統合、アクティビティ、およびデザインパターンをサポートします。

また、料金も異なります。
標準は状態遷移の回数に基づき、月に4000回の無料利用枠があり。
対してExpressは、ワークフローのリクエスト回数とワークフロー実行時間、使用メモリ量に基づくので少し複雑です。

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

コードを以下のチュートリアル提供のコードに置換します。
Lambdaエラー時の対応をステートマシンに設定するのがベストプラクティスですが、今回は行いません。

```
{
  "Comment": "A Hello World example of the Amazon States Language using an AWS Lambda function",
  "StartAt": "HelloWorld",
  "States": {
    "HelloWorld": {
      "Type": "Task",
      "Resource": "メモしたLambdaARN",
      "End": true
    }
  }
}
```

![スクリーンショット 2021-07-18 19.10.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/d596cb78-638b-954d-8837-ac0f7663bbfc.png)

このコードは、Amazon States Language（ASL）と呼ばれるJSON形式の独自言語です。
Step Functionsの用語Stateは、ステートマシンの処理単位だと思えばイメージしやすいと思います。
ステートマシンにはいくつものStateがあり、そのStateたちがどのように処理されているのかを設定しているのがステートマシンです。
AWSから離れますが、状態遷移（ステートマシン）図でいうと、一つ一つのコンポーネントがStateです。

上記のコードを簡単に説明します。

Comment:`ステートマシンの説明`
StartAt:`ステートマシンで最初に実行するStateを指定`
States:`Stateのセットを含むオブジェクト`
Type:`Stateのタイプ。Taskの場合、ステートマシンによって実行される単一の作業単位を表し、今回でいうとLambda。`
Resource:`URI。特に実行する特定のタスクを一位に識別するARN`
End:`trueの場合、そのState実行後にステートマシンが終了状態となる。`

https://docs.aws.amazon.com/step-functions/latest/dg/concepts-states.html

新しいロールの作成を選択します。

![スクリーンショット 2021-07-18 19.12.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/f43725fc-5186-34aa-5d69-afb3ca1a1b42.png)

チュートリアルではログは取得していませんが、簡単にログ記録ができたので有効化してみました。

![スクリーンショット 2021-07-18 19.12.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/b0122ae3-d442-6670-c5ae-13587036759c.png)

## ステートマシン実行

完成したステートマシンを実行します。

![スクリーンショット 2021-07-18 21.26.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/92da1583-c46d-ee2a-a633-f68bac1b25d7.png)

名前を指定すると、実行の識別がしやすくなります。
今回はチュートリアルなので、自動で生成されたIDのまま実行。
入力をチュートリアルのサンプルデータに置換します。

```
{
    "who" : "AWS Step Functions"
}
```

![スクリーンショット 2021-07-18 21.27.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/81095d9a-5c48-5ae4-2fc4-b2942ce0a80d.png)

実行が完了したので、ステップ出力を確認し、Lambdaが正常に動作したことを確認します。
`Hello, AWS Step Functions!`となっていれば成功です。


![スクリーンショット 2021-07-18 21.27.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/58346287-1151-69de-f44b-e8f987469c1d.png)

下画面には実行イベント履歴が残っています。
この履歴はExpressだと残りません。


>標準ワークフローとは異なり、エクスプレスワークフローはAWSステップ関数に実行履歴を記録しません。Expressワークフローの実行履歴と結果を表示するには、Amazon CloudWatchLogsへのログを設定する必要があります。ログを公開しても、実行がブロックされたり遅くなったりすることはありません。

https://docs.aws.amazon.com/step-functions/latest/dg/cw-logs.html


![スクリーンショット 2021-07-18 21.33.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/7f9cc9bb-e4a2-7479-4238-33c2330e4d5a.png)

今回、CloudWatch Logsを有効にしましたが、ロググループには上記実行イベント履歴が送信されていました。

![スクリーンショット 2021-07-18 21.34.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344711/8700de49-970b-0453-d0ec-fd1697d2d46d.png)

ログ分析がしたいときや、Expressでイベント履歴を残したい時は、CloudWatch Logsの有効化が必要ですね。

# おわりに

AWS Step Functionsの固有用語にさえ慣れれば、一気に理解が深まりました。
他サービスとの連携ができて面白そうなサービスなので、AWSでソリューションが紹介されていれば試してみたいです。