AWS Step Functions 入門 — コンソールとTerraformで学ぶハンズオン

目次

AWS Step Functions 入門: コンソールとTerraformで学ぶワークフローオーケストレーション

公開日: 2026-04-11
難易度: 初級〜中級
所要時間: 約60分
タグ: AWS, Step Functions, Terraform, ハンズオン, サーバーレス

この記事で学ぶこと
– AWS Step Functionsの基本概念とユースケース
– AWSコンソールでのステートマシン作成・実行
– Terraformで同等構成をInfrastructure as Codeで管理


セクション1: AWS Step Functions とは

AWSで複数のサービスやLambda関数を組み合わせた処理を作るとき、「どの順番で呼び出すか」「エラーが出たらどうするか」「並列で動かすには?」といった制御ロジックを自前で書くのは意外と大変です。そこで活躍するのが AWS Step Functions です。


1. AWS Step Functions の概要

AWS Step Functions は、AWSが提供するサーバーレスのワークフローオーケストレーションサービスです。複数のAWSサービスや処理ステップを ステートマシン(State Machine) として定義し、視覚的なフロー(ビジュアルワークフロー)として管理・実行できます。

処理の流れは ステート(State) の集合体として表現されます。各ステートは「何をするか」を定義し、それぞれが ステート遷移(State Transition) によって次の処理へとつながります。このフローはAWSマネジメントコンソール上でグラフィカルに確認できるため、複雑なロジックでも全体像を直感的に把握できます。

主な特徴

特徴説明
サーバーレスインフラ管理不要。実行した分だけの従量課金
エラーハンドリングリトライ・キャッチ(Catch)を宣言的に定義可能
並列処理Parallel ステートで複数ブランチを同時実行
待機・タイムアウトWait ステートやHeartbeatSecondsで柔軟な待機制御
豊富なAWSサービス連携Lambda、ECS、DynamoDB、SageMakerなど200以上のサービスと直接統合(SDK統合)

2. ユースケース

Step Functionsは幅広いシナリオで活用されています。代表的なユースケースを紹介します。

2-1. データ処理パイプライン

S3にファイルがアップロードされたことをトリガーに、Lambda関数でのバリデーション → データ変換 → DynamoDBへの書き込み → 通知送信、という一連の処理をStep Functionsで管理します。各ステップのエラーハンドリングや再実行ロジックを一元管理できます。

2-2. マイクロサービスの連携・オーケストレーション

複数のマイクロサービス(Lambda関数やECSタスク)を呼び出す際に、呼び出し順序や依存関係をStep Functionsで制御します。各サービス間の「糊(グルーコード)」をアプリケーションコードに書かずに済むため、疎結合なアーキテクチャを維持できます。

2-3. 人間の承認フロー(Human Approval)

Wait for a Callback パターンを使い、ワークフローの途中で人間の承認を待つフローを実現できます。たとえば「申請 → 管理者メール通知 → 承認/却下ボタン押下 → 後続処理継続」といったフローを、長時間(最大1年)待機しながら実行できます。

2-4. MLワークフロー(Amazon SageMaker連携)

SageMakerとのネイティブ統合を使って、データ前処理 → モデルトレーニング → 評価 → 条件分岐によるデプロイ、という機械学習パイプラインをStep Functionsで構築できます。MLOpsの自動化に広く使われています。

2-5. 定期バッチ処理

EventBridge(旧CloudWatch Events)でスケジュールトリガーを設定し、夜間バッチ処理をStep Functionsで実行します。処理の進捗をAWSコンソールで視覚的に確認でき、失敗時の再実行も容易です。


3. 料金の概要

Step Functionsには用途に応じて2種類のワークフロータイプがあります。

Standard Workflow(標準ワークフロー)

  • 課金単位: ステートの遷移回数(State Transitions)
  • 最大実行時間: 1年
  • 実行履歴: 90日間保持(コンソールで確認可能)
  • 用途: 長時間・低頻度・処理の可視性が重要なフロー(Human Approvalなど)
  • 無料枠: 毎月4,000回のステート遷移

Express Workflow(エクスプレスワークフロー)

  • 課金単位: 実行回数 + 実行時間(GB-秒)
  • 最大実行時間: 5分
  • 実行履歴: CloudWatch Logsに転送(デフォルトではコンソール非表示)
  • 用途: 高頻度・短時間の処理(IoTイベント処理、ストリーミングデータ変換など)
  • 無料枠: 毎月1万回の実行

選び方の目安: 処理時間が5分以内で大量実行するなら Express Workflow、それ以外(承認フロー・長時間バッチなど)は Standard Workflow を選びましょう。


概念とユースケースを把握したところで、次のセクションでは実際にAWSコンソールからStep Functionsのステートマシンを作成するハンズオンを進めます。


セクション2: AWSコンソールでのハンズオン

注意: AWSコンソールの画面レイアウトやUI表記は定期的に変更されることがあります。本記事の手順と異なる場合は、画面の案内に従いながら同等の操作を行ってください。

このセクションでは、AWSコンソールを使って実際にStep Functionsのステートマシンを作成・実行します。「Hello World」相当のシンプルなステートマシンから始め、最終的にLambda関数と連携するステートマシンまで段階的に学びます。


2-1. 事前準備

IAMロールの準備

Step Functionsのステートマシンが他のAWSサービス(Lambda等)を呼び出すには、適切なIAMロールが必要です。IAMロールの取得方法は2通りあります。

方法A: ステートマシン作成時に自動生成(推奨・初心者向け)

AWSコンソールでステートマシンを作成する際、「新しいロールの作成」を選択すると、Step Functionsが必要な権限を自動的に判断してIAMロールを生成します。ハンズオン目的であれば、この方法が最も簡単です。

方法B: 事前にIAMロールを手動作成

特定の権限を細かく制御したい場合は、事前にIAMロールを作成しておきます。

  1. AWSコンソール → IAMロール → 「ロールを作成」をクリック
  2. 信頼されたエンティティのタイプ: AWSのサービス
  3. ユースケース: Step Functions を選択 → 「次へ」

図1: IAMロール作成 — Step Functionsのユースケースを選択

  1. 許可ポリシーで AWSLambdaRole を追加(Lambda連携が必要な場合)
  2. ロール名: StepFunctionsHandsOnRole など任意の名前を入力
  3. 「ロールを作成」をクリック

最小権限の原則: 本番環境では必要最小限の権限のみを付与してください。ハンズオンでは CloudWatchLogsFullAccess を追加すると実行ログの確認が容易になります。


2-2. シンプルなステートマシンの作成

PassステートとSucceedステートを組み合わせた「Hello World」相当のステートマシンを作成します。

手順

① Step Functionsコンソールを開く

  1. AWSコンソール上部の検索バーに Step Functions と入力
  2. AWS Step Functions をクリックして開く

図2: AWSコンソール検索バーでStep Functionsを検索

② ステートマシンの作成を開始

  1. 左サイドバーの 「ステートマシン」 をクリック
  2. 右上の 「ステートマシンの作成」 ボタンをクリック

図3: ステートマシン一覧画面と「ステートマシンの作成」ボタン

③ 作成方法を選択

作成画面では以下の選択肢が表示されます。

  • テンプレートから開始: AWSが用意したサンプルテンプレートを使用
  • 空白から作成: ゼロから定義を記述

ここでは 「空白から作成」 を選択します。

④ ワークフロー定義(ASL)を記述

エディタ画面が表示されます。右側の「コード」タブを選択し、以下のASL(Amazon States Language)を貼り付けます。

{  "Comment": "Hello World ステートマシン",  "StartAt": "HelloWorld",  "States": { "HelloWorld": {"Type": "Pass","Result": {  "message": "Hello, Step Functions!"},"ResultPath": "$.output","Next": "SuccessState" }, "SuccessState": {"Type": "Succeed" }  }}

ASL解説:

フィールド意味
Commentステートマシンの説明(省略可)
StartAt最初に実行されるステートの名前
States全ステートの定義マップ
Type: "Pass"入力をそのまま(または加工して)出力するステート
ResultPassステートが返す固定値
ResultPath結果の出力先パス($.output に書き込む)
Next次に遷移するステートの名前
Type: "Succeed"ワークフローを正常終了するステート

図4: ASLエディタにコードを貼り付けた状態

コードを貼り付けると、左側のビジュアルエディタにステートマシンのグラフがリアルタイムで反映されます。

⑤ ステートマシンの設定

「次へ」をクリックし、設定画面に進みます。

  • ステートマシン名: HelloWorldStateMachine(任意)
  • タイプ: Standard(今回はデフォルトのままでOK)
  • 実行ロール:
  • 「新しいロールの作成」を選択(自動生成の場合)
  • または「既存のロールを使用する」で手順2-1で作成したロールを選択

図5: ステートマシン設定画面

⑥ 作成を完了

  1. 設定を確認して 「ステートマシンの作成」 をクリック
  2. 「ステートマシンが作成されました」のメッセージが表示されれば完了です

2-3. ステートマシンの実行

作成したステートマシンを実際に実行して、状態遷移を確認します。

手順

① 実行を開始

  1. ステートマシン詳細画面(作成直後に表示される画面)で 「実行の開始」 ボタンをクリック

図6: ステートマシン詳細画面と「実行の開始」ボタン

② 入力JSONを指定

実行開始ダイアログが表示されます。

  • 名前: 実行に名前をつけられます(省略するとランダムなUUIDが自動設定)
  • 入力: 実行時の入力データをJSON形式で指定します

以下のJSONを入力欄に貼り付けます。

{  "message": "Hello Step Functions!"}

図7: 実行開始ダイアログと入力JSON

「実行の開始」 ボタンをクリックします。

③ 実行グラフで状態遷移を確認

実行詳細画面に遷移します。グラフビューでステートの遷移が視覚的に表示されます。

  • 緑色: 成功したステート
  • 青色: 現在実行中のステート
  • 赤色: 失敗したステート

今回のシンプルなステートマシンではほぼ瞬時に完了し、HelloWorldSuccessState の流れが緑色で表示されます。

図8: 実行グラフ — 全ステートが緑色(成功)の状態

④ 実行結果の確認

画面下部の 「実行結果」 タブを確認します。

  • 出力: ステートマシンの最終出力JSONが表示されます
    json
    {
    "message": "Hello Step Functions!",
    "output": {
    "message": "Hello, Step Functions!"
    }
    }

  • 実行イベント履歴: 各ステートの開始・終了イベントが時系列で確認できます

図9: 実行結果タブと出力JSON

ポイント: ResultPath: "$.output" の設定により、元の入力JSON($.message)を保持したまま、Passステートの結果($.output)が追記された形で出力されます。


2-4. Lambdaを呼び出すステートマシン(発展)

より実践的なユースケースとして、Lambda関数を呼び出すTaskステートを追加します。

事前準備: Lambda関数の作成

  1. AWSコンソール → Lambda「関数の作成」
  2. 以下の設定で関数を作成:
  3. 関数名: StepFunctionsHelloLambda
  4. ランタイム: Python 3.12(または任意のランタイム)
  5. 実行ロール: 基本的なLambdaロール(デフォルト)

  6. 関数コードを以下に書き換えて 「Deploy」 をクリック:

import jsondef lambda_handler(event, context): name = event.get("name", "World") return {  "statusCode": 200,  "message": f"Hello, {name}! from Lambda" }

Taskステートを含むASL

Lambda関数のARNを取得し(Lambda関数詳細画面の右上に表示)、以下のASLを使ってステートマシンを作成します。

{  "Comment": "Lambda連携 ステートマシン",  "StartAt": "InvokeLambda",  "States": { "InvokeLambda": {"Type": "Task","Resource": "arn:aws:states:::lambda:invoke","Parameters": {  "FunctionName": "arn:aws:lambda:ap-northeast-1:123456789012:function:StepFunctionsHelloLambda",  "Payload.$": "$"},"ResultSelector": {  "body.$": "$.Payload"},"ResultPath": "$.lambdaResult","Next": "SuccessState" }, "SuccessState": {"Type": "Succeed" }  }}

注意: FunctionName の値は自分の環境のLambda関数ARNに書き換えてください。ARNは arn:aws:lambda:<リージョン>:<アカウントID>:function:<関数名> の形式です。

Taskステートの主要フィールド解説:

フィールド意味
Type: "Task"外部サービスを呼び出すステート
Resource呼び出すAWSサービスのARN(Lambdaの統合ARN)
Parameters呼び出し時のパラメータ。.$ サフィックスで動的な値を参照可能
ResultSelectorLambda応答から必要なフィールドのみを抽出
ResultPath結果を格納するJSONパス

実行して確認

以下の入力JSONで実行します。

{  "name": "Step Functions"}

実行が成功すると、出力に以下のような結果が含まれます。

{  "name": "Step Functions",  "lambdaResult": { "body": {"statusCode": 200,"message": "Hello, Step Functions! from Lambda" }  }}

図10: Lambda連携ステートマシンの実行グラフ


セクションまとめ

このセクションでは以下を実践しました。

項目内容
IAMロール準備自動生成または手動作成の2パターン
シンプルなステートマシンPassステートとSucceedステートによるHello World
ステートマシンの実行コンソールから入力JSONを指定して実行・結果確認
Lambda連携(発展)TaskステートでLambda関数を呼び出す実践例

コンソールでの操作が身に付いたところで、次のセクションではTerraformを使って同じステートマシンをコードとして定義・デプロイする方法を解説します。


セクション3: Terraformで同等構成を構築する

コンソールで作成したStep Functions ステートマシンを、今度はTerraformを使ってコード化してみましょう。Infrastructure as Code(IaC)で管理することで、環境の再現性が高まり、チームでの共有や変更管理が容易になります。


3-1. 前提条件

作業を始める前に、以下の環境が整っていることを確認してください。

  • Terraform: バージョン 1.0 以上がインストール済み
    bash
    terraform version
    # Terraform v1.x.x 以上であることを確認
  • AWS CLI: aws configure で認証情報が設定済み
    bash
    aws sts get-caller-identity
    # アカウントIDとIAMユーザー/ロール情報が返ってくれば設定完了
  • IAM 権限: 以下の操作権限が必要です
  • iam:CreateRole / iam:AttachRolePolicy / iam:PutRolePolicy
  • states:CreateStateMachine / states:DeleteStateMachine

3-2. ディレクトリ構成

以下のディレクトリ構成でプロジェクトを作成します。

step-functions-handson/├── main.tf├── variables.tf├── outputs.tf└── statemachine/ └── definition.json
mkdir -p step-functions-handson/statemachinecd step-functions-handson

3-3. Terraformコード

variables.tf

まず変数定義ファイルを作成します。

# variables.tfvariable "aws_region" {  description = "AWSリージョン"  type  = string  default  = "ap-northeast-1"}variable "state_machine_name" {  description = "Step Functions ステートマシン名"  type  = string  default  = "hello-world-state-machine"}

main.tf

メインのリソース定義ファイルです。IAMロールとStep Functionsステートマシンを定義します。

# main.tfterraform {  required_version = ">= 1.0"  required_providers { aws = {source  = "hashicorp/aws"version = ">= 5.0" }  }}provider "aws" {  region = var.aws_region}# Step Functions 実行用 IAM ロールresource "aws_iam_role" "sfn_role" {  name = "${var.state_machine_name}-role"  assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [{  Action = "sts:AssumeRole"  Effect = "Allow"  Principal = { Service = "states.amazonaws.com"  }} ]  })}# CloudWatch Logs への書き込み権限(実行ログ記録用)resource "aws_iam_role_policy" "sfn_logging_policy" {  name = "${var.state_machine_name}-logging-policy"  role = aws_iam_role.sfn_role.id  policy = jsonencode({ Version = "2012-10-17" Statement = [{  Effect = "Allow"  Action = [ "logs:CreateLogDelivery", "logs:GetLogDelivery", "logs:UpdateLogDelivery", "logs:DeleteLogDelivery", "logs:ListLogDeliveries", "logs:PutResourcePolicy", "logs:DescribeResourcePolicies", "logs:DescribeLogGroups"  ]  Resource = "*"} ]  })}# Step Functions ステートマシンresource "aws_sfn_state_machine" "hello_world" {  name  = var.state_machine_name  role_arn = aws_iam_role.sfn_role.arn  definition = file("statemachine/definition.json")  tags = { Environment = "handson" ManagedBy= "terraform"  }}

statemachine/definition.json

コンソールで作成したのと同じASL(Amazon States Language)定義を外部ファイルとして管理します。

{  "Comment": "Hello World ステートマシン",  "StartAt": "HelloWorld",  "States": { "HelloWorld": {"Type": "Pass","Result": {  "message": "Hello, Step Functions!"},"ResultPath": "$.output","Next": "SuccessState" }, "SuccessState": {"Type": "Succeed" }  }}

outputs.tf

デプロイ後に確認したい情報を出力します。

# outputs.tfoutput "state_machine_arn" {  description = "Step Functions ステートマシンの ARN"  value = aws_sfn_state_machine.hello_world.arn}output "state_machine_name" {  description = "Step Functions ステートマシン名"  value = aws_sfn_state_machine.hello_world.name}

3-4. デプロイ手順

ファイルがすべて作成できたら、Terraformでデプロイします。

初期化

terraform init
Initializing the backend...Initializing provider plugins...- Finding hashicorp/aws versions matching ">= 5.0.0"...- Installing hashicorp/aws v5.x.x...Terraform has been successfully initialized!

実行計画の確認

terraform plan

作成されるリソースを確認します。以下の3リソースが + で表示されれば正常です。

Plan: 3 to add, 0 to change, 0 to destroy.Changes to Outputs:  + state_machine_arn  = (known after apply)  + state_machine_name = "hello-world-state-machine"

デプロイ実行

terraform apply

yes を入力して実行します。

Do you want to perform these actions?  Terraform will perform the following actions:  # ... (省略)  Enter a value: yesApply complete! Resources: 3 added, 0 changed, 0 destroyed.Outputs:state_machine_arn  = "arn:aws:states:ap-northeast-1:123456789012:stateMachine:hello-world-state-machine"state_machine_name = "hello-world-state-machine"

3-5. 動作確認

デプロイが完了したら、ステートマシンを実行して動作を確認しましょう。

AWS CLIで実行

# ARNを変数に設定(terraform outputから取得)STATE_MACHINE_ARN=$(terraform output -raw state_machine_arn)# ステートマシンを実行aws stepfunctions start-execution \  --state-machine-arn "$STATE_MACHINE_ARN" \  --input '{"message": "Hello from Terraform!"}' \  --region ap-northeast-1

実行が成功すると、以下のようなレスポンスが返ります。

{ "executionArn": "arn:aws:states:ap-northeast-1:123456789012:execution:hello-world-state-machine:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "startDate": "2026-04-11T07:00:00.000000+09:00"}

実行結果を確認

# 実行ARNを使って結果を確認EXECUTION_ARN="<上記の executionArn>"aws stepfunctions describe-execution \  --execution-arn "$EXECUTION_ARN" \  --region ap-northeast-1

"status": "SUCCEEDED" が確認できれば成功です。

AWSコンソールで確認

  1. AWS マネジメントコンソール → Step Functions に移動
  2. ステートマシン 一覧に hello-world-state-machine が表示されることを確認
  3. ステートマシンをクリック → 実行を開始 → 実行履歴でグラフビューを確認

3-6. クリーンアップ

ハンズオン終了後は、不要な課金を避けるためにリソースを削除しましょう。

terraform destroy
Do you really want to destroy all resources?  Terraform will destroy all your managed infrastructure, as shown above.  There is no undo. Only 'yes' will be accepted to confirm.  Enter a value: yesDestroy complete! Resources: 3 destroyed.

注意: terraform destroy を実行するとTerraformで管理しているすべてのリソースが削除されます。本番環境では絶対に使用しないでください。


まとめ

このセクションでは、コンソールで作成したStep Functionsステートマシンと同等の構成をTerraformで構築しました。

項目内容
作成リソースIAMロール、IAMポリシー、ステートマシン
定義ファイルstatemachine/definition.json(ASL定義を外部化)
プロバイダーhashicorp/aws >= 5.0
デフォルトリージョンap-northeast-1(東京)

TerraformによるIaCを採用することで、コードレビュー可能な変更管理環境の再現性が実現できます。次のセクションでは、今回の学習を振り返り、さらに発展させるためのトピックを紹介します。


セクション4: まとめと次のステップ

4-1. 本記事のまとめ

本記事では、AWS Step Functions の基本概念から実際の構築手順まで、ハンズオン形式で学びました。以下に学んだポイントを整理します。

  • Step Functions の基本: ステートマシンとステートの概念、Amazon States Language (ASL) によるワークフロー定義を理解した
  • コンソールによる構築: AWS マネジメントコンソールから GUI 操作でステートマシンを作成・実行・デバッグする手順を習得した
  • Terraform による IaC 化: aws_sfn_state_machine リソースを使ってインフラをコードで管理し、再現性のある環境構築ができるようになった
  • Lambda との連携: Task ステートを使って AWS Lambda 関数をオーケストレーションし、サーバーレスワークフローを実現した
  • 実行履歴の確認: Step Functions コンソールの実行履歴とビジュアルフローで、各ステートの入出力・エラーをトレースする方法を学んだ
  • IAM ロールの設計: Step Functions が Lambda や他の AWS サービスを呼び出すために必要な IAM ロール・ポリシーの最小権限設計を理解した
  • Standard Workflow の特性: 最大 1 年の実行期間、正確に 1 回の実行保証、詳細な実行履歴という Standard Workflow の特徴を把握した

4-2. Step Functions のより高度な使い方(次のステップ)

本記事では Standard Workflow の基礎を扱いましたが、Step Functions にはさらに多くの機能があります。以下のトピックを次回以降の記事で順次解説予定です。

並列処理(Parallel ステート)

複数のブランチを同時実行して処理を高速化します。例えば「画像のサムネイル生成」と「メタデータ抽出」を並行して行うユースケースを扱います。

条件分岐(Choice ステート)

入力値に応じてフローを動的に切り替えます。StringEqualsNumericGreaterThan などの比較演算子を使ったルーティングロジックを解説します。

エラーハンドリング(Retry / Catch)

一時的なネットワークエラーや Lambda のタイムアウトを自動リトライし、失敗時にフォールバック処理へ誘導する堅牢なワークフロー設計を学びます。

Express Workflow(高頻度・短時間処理向け)

最大 5 分、秒間 100,000 回以上の実行に対応した Express Workflow の特性と、Standard Workflow との使い分け基準を解説します。

EventBridge との連携(イベント駆動ワークフロー)

S3 イベントや DynamoDB Streams をトリガーに Step Functions を自動起動するイベント駆動アーキテクチャパターンを紹介します。

SageMaker パイプラインとの連携

ML ワークフローを Step Functions から制御し、データ前処理・学習・評価・デプロイを一貫して管理する MLOps 構成を解説します。


4-3. 参考リンク

本記事の内容をさらに深掘りするための公式ドキュメントです。


4-4. 記事フッター


本記事は「AWS ハンズオン TechBlog」シリーズの第1回です。
次回: [次のテーマ(未定)]

最新情報をチェックしよう!