AWS Step Functionsでつまずいたポイントを“実際に使って”まとめてみた
Back to Top
概要
#「AWS Certified Developer - Associate (DVA-C02) 」を受験するにあたり関連する内容を知識のみでなく実際に手を動かしながら理解を深めていこうと思い立ち、その際に躓いたところだったりわかりにくかった概念などを備忘録としてまとめておき、後から見返せるよう残しておきたいと思います。
今回は試験の範囲にも含まれているAWS Step Functions(以降Step Functions)について普段あまり触ることのなかったサービスだったので使ってみていこうと思います!
AWS Step Functionsとは
#細かい部分や言葉の定義などは公式に譲るとして、簡単にどんなサービスかを表現すると「AWSサービス用オーケストレーションツール」が適切だと思います。
基本的にはAWS SDKなどのAPIをステートマシンと呼ばれるフローに組み込み、AWSサービスを連携させたデータ処理などを実現させることができるサービスかなと思います。
具体的にStep Functionsのユースケースとしては、
- データ処理フロー
- 機械学習ワークフロー
- マイクロサービスのオーケストレーション
- セキュリティオートメーション
が公式でも挙げられていました。
アップロードした画像に対してサムネイルとサイズ変換を並行して実施させたり、構造化されているデータに対して反復処理を実施できたりするみたいです。
フロー中でエラーが起きた際の再試行なども実装できるので、エラーハンドリングにも対応しているのはありがたいですね。
概念や使い方の理解
#さて、知見の少ないサービスに対してはチュートリアルからサクッと触ってみてイメージをつかむのが早いと思うので、公式チュートリアルに沿って手を動かし、Step Functionsの特徴や使い方を整理していきたいと思います。
チュートリアルの内容を1から全部載せる意味はあまりないので、進める中で重要そうな概念や使い方を残しておこうと思います。
1. ワークフロー(ステートマシンと同義)設定の仕方は2種類
#Step Functionsでワークフローを定義する方法は2パターンあり、
- Workflow StudioでGUIベース設定
- ASLというJSON ベースの構造化言語を使ってコードベースで設定
があります。
特にこだわりがなければWorkflow StudioでGUIベースで設定していけば問題ないと思います。
GUIベースで設定したとしても並行してASLでの定義もされているので、後から別の環境やメンバーに同じ設定を共有、なんてこともできますね。
ワークフローの大枠をGUIでちゃちゃっと定義しておいて、細かい部分をASLで作りこむ、みたいなやり方も使いやすそうかなと思いました。
(特にChoiceやMapフローをASLで最初から定義しようとするとぱっと見わかりにくいと感じたので)
2. ワークフローの実行がリアルタイムでグラフィカルに確認できる
#
各ステート(ワークフロー内のステップのこと)が成功・失敗しているかが一目でわかり、ステートへの入出力や定義内容も見えるのでどういう失敗が起きてて、どこの定義が間違っているのかが見つけやすい仕組みになっていると感じました。
ここで少しわかりにくいと感じたのが「イベント」という概念です。
これは、ステート(「イベントビューワー」の中だと「Step」カラムに表記されている)の中で行われている詳細なステートの状態変化にあたると理解しました。
この内容を「イベントビューワー」で見ることができます。
3. タスクの種類
#タスクタイプで記載がある通り、以下4種類のタスクタイプが存在しているようです。
それぞれのタイプとその特徴を簡単にまとめておくと、
- アクティビティ
以下公式の言葉も借りながらになりますが、アクティビティタイプのタスクというのは、
Step Functionsの外部(=アクティビティワーカー)、つまり任意の場所にホストされているアプリケーションとステートを紐づける方法のことを指します。
外部アプリ側でポーリングの仕組みを実装しておく必要があったり、割と手はかかりそうですがAWS外のアプリを含めた管理ができる仕組みがあることはありがたいですね。
- Lambda 関数
これは名前が示す通り、ワークフローの中でLambda関数を呼び出すタイプのタスクになります。
- サポートされるAWSのサービス
これは以降でまとめているサービスの統合についての内容を実行するためのタイプになります。
- HTTPタスク
こちらも公式の言葉を借りると、StripeやSalesforceなどのサードパーティーSaaSアプリケーションをワークフローの中で呼び出せるタイプになります。
ただ、実装するにはAPIでの認可に必要なヘッダー、本文、およびクエリパラメータを含めた「EventBridge接続」というものを別途作成しておく必要があり、割と手がかかりそうなタスクタイプの印象です。
導入としては深くなりすぎるので公式 - HTTP タスクの接続に詳細は譲ります。
上記4タイプのタスクをどうやって定義するかも公式に記載の通りですが、どのタイプを指定するかでStep Functionsで行う内容が決まると思うのでポイントとして挙げておきました。
AWS上で構築しているアプリケーションであれば「Lambda関数」タイプと「サポートされるAWSのサービス」タイプでこと足りそうですが、既存の外部アプリケーションやSaaSサービスの利用を考慮にいれると手間がかかってきそうですね。
また、若干ややこしいのが、Typeフィールドでこの種類を使い分けるのではなく、Resourceフィールドに指定するARNの書き方で使い分けているようです。
4. サービスの統合について
#タスクタイプとしてサポートされたサービスのAPIアクションを選択した場合の話になります。
これも少しややこしいと感じた概念で、Step Functionsから様々なAWSサービスを呼び出すことを「サービスの統合」という概念として定義しています。
その「サービスの統合」にも種類があり、
- AWS SDK 統合
- 最適化された統合
- クロスアカウントアクセス
の3種類が存在しています。(クロスアカウントアクセスについての詳細は省略)
さらに、それぞれの種類において、
- レスポンスのリクエスト (デフォルトの挙動)
- ジョブの実行 (.sync)
- コールバックの待機 (.waitForTaskToken)
の3パターンの挙動が存在しています。
これをまとめている表が公式のページに記載されている内容になってます。
見てもらえればわかりますが、各種類の中でもサポートしていないパターンがあったりするので、使う際には確認が必要になると思います。
また、簡単に「AWS SDK 統合」「最適化された統合」の違いを述べておくと、
AWS SDK統合 | 最適化された統合 |
---|---|
AWS SDK を使用した標準 API コールとまったく同じように機能 | Step Functions によってカスタマイズされているAPIコール |
という理解になり、公式的には「最適化された統合」を使うことを薦めています。
カスタマイズされているというのは、APIに対して指定できるオプションや引数がStep Functions側で使いやすいように用意されているということです。
AWS SDK統合の場合はAPIのパラメータを直接指定するので、SDKを使う場合と変わりない方法といえます。
公式的にはなるべく「最適化された統合」を使うことを薦めていますが、圧倒的に「AWS SDK 統合」で使えるサービスのほうが多いので、ワークフローで定義したいサービスが「AWS SDK 統合」と「最適化された統合」の両方でサポートされているのであれば「最適化された統合」側を利用する感じでいいのかなと思いました。
所感
#AWS LambdaでSDKコマンドを組み合わせて、プログラミングの文法でループなどのロジックを実装しても似たようなことはできそうだなと感じましたが、それはあくまでシンプルな内容や実行時間が短い処理に限られるのかなと思いました。
実際、エラーハンドリングやデータの保持、Lambda関数同士の連携などをLambdaのみで作りこもうとすると大変かつ管理もしにくいと思うので、そういう観点から「複数のステップからなるプロセスを構築する場合」や「様々なサービスを絡めた処理の分岐や並列実行が必要な場合」、「各ステップの実行状況やデータフローを視覚的に把握したい場合」などの場合にStep Functionsを使っていくのがいいのかなと思いました。
もちろん、見方によっては「ASLの理解に学習コストがかかる」、「課金体系によるコスト面の問題」、「Lambdaを絡めるなら結局コードの保守は必要になりそう」など懸念する点もあると思いますが、この辺りはやはり目的に対して、サービス選定段階でよく見極めたうえで使う必要がありそうだなと感じました。
おわりに
#今回はAWS Step Functionsに焦点を当てて基本的な内容にはなりますが自分なりに特徴や使い時などを整理できたと思います。
今後の取り組みとしては、上記でも紹介したユースケースについて実際に試していきながら、「フロー定義の時に躓いたこと」や「サービス統合の細かい留意事項」などが出てくると思うので、ぼちぼちその内容をまとめていけたらなと思います。
最後まで目を通していただきありがとうございました。