AWS Step Functions で人による承諾まで待機する方法を試してみた

# はじめに
この記事では AWS Step Functions 内で他のサービスと統合し、人による承諾までワークフローを待機させる方法を紹介します。


# ワークフローの待機について
AWS Step Functions内で `.waitForTaskToken` を使用することでコールバックが返されるまでワークフローを待機させることができます[^1]。

[^1]: [タスクトークンのコールバックまで待機する](https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/connect-to-resource.html#connect-wait-token)

# 試してみる
公式ドキュメントに  [人間による承諾プロジェクト例をデプロイする](https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/tutorial-human-approval.html) があるので実施してみます。開発者ガイドに実行可能なテンプレートが整備されているのは便利ですね。

## 実行結果
CloudFormationの実行が完了すると Step Functions が作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296651/68e6f713-b7e8-558a-8b42-cc4930a70590.png)

Step Functions を実行するとSNS通知先で登録したメールアドレスにEメールが届きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296651/4d40002c-a9ea-2412-12d2-414568c441c6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296651/ebd508ec-77a6-5797-ba0f-30ed00bef22c.png)


その間、Step Functions のワークフローは停止しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296651/5e44b8b0-481b-1e10-b18b-13bea7a1d984.png)

Eメールの approve のリンクをクリックするワークフローが再開されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296651/8807b676-26ed-6f94-586b-198edd3aeb10.png)

これで公式ドキュメントは終了なのですが、Eメールのリンクをクリックから Step Functions 再開までの流れが理解できなかったため、中身を詳しく見ていきます。

## デプロイされた Step Functions の詳細
CloudFormationを確認すると、実行されるAWSサービスとして `API Gateway`, `SNS`, `Lamnda①(LambdaHumanApprovalSendEmailFunction)`, `Lambda②(LambdaApprovalFunction)` の4つのリソースが作成されています。
SNSはメール通知に用いているとわかりますが、API Gateway と Lamnbda 2つの関係性がまだわかりません。

CloudWatch logを確認してみると、`LambdaHumanApprovalSendEmailFunction` → `LambdaApprovalFunction` の順番で実行されているようです。そのため、`LambdaHumanApprovalSendEmailFunction` の中身から確認していきます

### LambdaHumanApprovalSendEmailFunction の詳細
`LambdaHumanApprovalSendEmailFunction` の ソースコードを見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296651/c4938460-5f41-69e4-51b1-4723f08743fa.png)

39行目以降で SNS トピックを作成しており、`LambdaHumanApprovalSendEmailFunction` → SNSによるEメール発行 の順番で実行されているようです。
Eメールの本文は 31～37行目で作成されており、通知で届いたEメール文章とも一致します。
19行目で API Gateway エンドポイントを指定しており、作成した API Gateway をこの後に使っていそうです。
また22行目, 25行目で `&taskToken` というパラメータを設定しており、ここで Step Functions の実行ワークフローのトークンを付与していそうです。

`LambdaHumanApprovalSendEmailFunction` では API Gateway のエンドポイントや Step Functions のトークンを指定して Approve/Reject のURLを作成していることがわかりました。
次に、Approve/Reject をクリック先である API Gateway の動きを追っていきます。

### API Gateway の詳細
API Gateway の構成はシンプルで、エンドポイントに来たリクエストを Lamnda につなげているようです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296651/f8f65668-1263-e1f5-a772-c1e0e8df3a3b.png)

あとは接続先Lambdaである `` の詳細を確認すれば動きがつかめそうです。

### LambdaApprovalFunction の詳細
`LambdaApprovalFunction` のソースコードを見てみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296651/b624a80e-4e0c-b5ce-a7c7-abd9b2af72af.png)

35～42行目でAPIリクエストのパラメータを読み取り、メッセージを設定しています。
その後、44行目で `output(message)` と `taskToken` の2つを Step Functions に送信しています。

この　`LambdaApprovalFunction` によって停止中の Step Functions が再開されていそうですね。
実際に Step Functions のステートマシン詳細を見てみると、`LambdaApprovalFunction` が作成するメッセージを基に、後続のフローを判断しているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296651/452f9b5b-0752-0d50-c0ae-060bacdc797f.png)

仮に複数のワークフローが待機中だとしても、`taskToken` により一意のワークフローを指定できそうです。

##  [人間による承諾プロジェクト例をデプロイする](https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/tutorial-human-approval.html)  の構成 
調べてみた結果を構成図に表してみると、以下のようになると理解しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296651/1cf5adcc-debd-c6d7-6597-2a9f84625f08.png)

# まとめ
今回の記事では AWS Step Functions 内で人による承諾までワークフローを待機させる方法を紹介しました。
最初は Lambda がコールバック待機しているのかと思っていましたが、実際には Step Functions として待機しているようですね。
実際に運用する際には API Gateway のエンドポイントの保護などセキュリティ面を考慮する必要がありそうですが、Lambda 単独では難しいフローを実現できる点が便利に感じます。