コンテンツにスキップ

step_functions pattern

概要

step_functions patternは、 AWS Step Functions により、AWS LambdaなどのAWSサービスを連携したワークフローを構築するモジュールです。

想定する適用対象環境

step_functionsは、Runtime環境で使用することを想定しています。

依存するpattern

step_functions patternは他のpattarnの実行結果に依存しません。独立して実行できます。

ただし、ワークフローに含めるAWSリソース(AWS Lambda関数など)は、事前に準備して頂く必要があります。

Lambda関数を作成する場合は、Eponaではlambda patternが用意されていますのでご参照ください。

構築されるリソース

このpatternでは、以下のリソースが構築されます。

リソース名 説明
AWS Step Functions ステートマシンを作成します。
AWS Identity and Access Management (IAM) ステートマシンを実行するために必要なロール、ポリシーを作成します。
Amazon CloudWatch ステートマシンのログを配置するロググループを作成します。
Amazon EventBridge ステートマシンを起動するトリガーとなるイベントや、実行状態を通知するためのイベントルールやターゲットを作成します。

構成図

AWS Step Functionsについて

AWS Step Functionsに関する概念や用語については公式ドキュメントの記載を参照してください。

AWS Step Functionsでは、1つの作業単位(たとえばLambda関数の実行など)をステートと呼び、これをつなげることでできる一連の流れ(ワークフロー)をステートマシンと呼びます。

ステートにはLambda関数の実行などのタスクの他に、待ち状態や分岐などの種類があり、これらを組み合わせることで様々なワークフローを構築できます。

ステートの種類についてはこちらを参照してください。

また、AWS Step Functionsで実現できるワークフローの概要については以下のドキュメントを参照してください。

ステートマシンの作成

ステートマシン定義

step_functions patternは、事前に作成していただいたステートマシン定義(json)を元にステートマシンを作成します。

ステートマシン定義はAmazonステートメント言語に従って記述する必要があります。

言語仕様に従ってテキストベースでの作成もできますが、 AWS Step FunctionsWorkflow Studio によりグラフィカルに作成した結果をエクスポートすることでも作成できます。

ステートマシンの定義にあたってはベストプラクティスもあわせて参照してください。

ℹ️ step_functions patternでは標準ワークフローの作成のみサポートしています。ワークフローの種類についてはこちらを参照してください。

ステートマシンが各タスクを実行する権限

ステートマシンがタスク内で他のAWSサービスを呼び出すためには、ステートマシンに適切な権限が与えられていることが前提となります。

AWSサービスは多岐にわたるためすべてを網羅はできませんが、step_functions patternでは、一部のタスクについては必要なロールを自動作成できます。

これは、入出力リファレンスにあるexecution_resource_arnsというパラメータを設定していただくことで可能となります。

下記のサンプルコードのように、タスク内で使用しているAWSリソースのARNを設定してください。

  execution_resource_arns = [
    "arn:aws:ecs:ap-northeast-1:000000000000:YourECSTask",
    "arn:aws:lambda:ap-northeast-1:000000000000:function:YourLambdaFunction"
  ]

対応しているAWSリソースは以下の通りです。


ℹ️ 例えばAmazon SQSキューのARNを指定した場合、 sqs:SendMessageを可能とするIAMポリシーがIAM実行ロールに付与されます。


これら以外のAWSリソースを使用する場合は、利用者側で必要な権限を持ったIAMポリシーを作成し、ステートマシンの実行ロールにアタッチしていただく必要があります。

たとえば、以下のようになります。

# ポリシードキュメント
data "aws_iam_policy_document" "document" {
  statement {
    ...
  }
}

# IAMポリシー
resource "aws_iam_policy" "policy" {
  policy = data.aws_iam_policy_document.document.json
  name   = "..."
}

# ポリシーをロールにアタッチ
resource "aws_iam_role_policy_attachment" "attachment" {
  role       = "..." # step_functions patternで作成されるロールの名称
  policy_arn = aws_iam_policy.policy.arn
}

なお、step_functions patternで作成されるロールはrole_arnrole_nameにて参照可能です。詳細は入出力リファレンスを参照してください。

AWSサービスごとに必要となる権限についてはこちらをご覧ください。

Lambdaのデプロイメントパイプラインとの統合について

EponaでのLambdaのデプロイメントパイプラインでは、AWS Lambdaエイリアス 機能を使用しています。

デプロイメントパイプラインで管理されているLambda関数をstep_functions patternに統合するには、Lambda関数のARNを指定する箇所に、エイリアスを含める必要があります。

ARNにエイリアス名を含める場合の書式は<Lambda関数のARN>:<Lambdaエイリアス名>となります。 また、ステートマシンに対して、エイリアス付きのLambda関数を実行する権限の付与が必要です。

ここでは、エイリアス名をdefaultとした場合の、ステートマシン定義およびステートマシンへの権限付与の例を記載します。

  • ステートマシン定義で、Lambda関数のエイリアスを指定する
{  
 "StartAt":"CallFunction",
 "States":{  
    "CallFunction": {  
       "Type":"Task",
       "Resource":"arn:aws:lambda:ap-northeast-1:123456789012:function:SampleFunction:default",
       "End": true
    }
  }
}
  • エイリアス付きのLambda関数を実行する権限を、ステートマシンに付与する
module "step_functions" {
  source = "git::https://gitlab.com/eponas/epona.git//modules/aws/patterns/step_functions?ref=v0.2.6"

  sfn_name        = "state-machine-lambda-alias"
  definition_json = file("sample-lambda-alias.json") # Lambdaエイリアスが指定されたステートマシン定義
  execution_resource_arns = [
    "arn:aws:lambda:ap-northeast-1:123456789012:function:SampleFunction:default"
  ]
  ...
}

ステートマシンの実行

ステートマシンの実行トリガー

ステートマシンはマネジメントコンソールやAWS CLIにより手動で起動できますが、スケジュールやイベントなどに基づいて、自動的に起動するようにも設定できます。

実行方法についてはこちらを参照してください。

step_functions patternでは、Amazon EventBridgeを使ったスケジュール実行とAmazon S3イベントでのトリガーをサポートしています。

なお、トリガーは複数種類同時に指定できます。

ℹ️ トリガー条件を同時に複数満たした場合、ステートマシンは同時並行して起動します。ただし、同時実行数には制限があります。詳細はこちらを参照してください。

Amazon EventBridgeを使ったスケジュール実行

schedule_expressionにスケジュール式を指定することで、Amazon EventBridgeを使用したスケジュール実行ができます。

cron()式あるいはrate()式で指定できます。

記述方法については、こちらを参照してください。

以下に設定例を示します。

module "step_functions" {
  ...
  schedule_configs = [
    {
      schedule_expression = "rate(5 minutes)"
      is_enabled = true
    },
    {
      schedule_expression = "cron(0/5 * * ? *)"
      is_enabled = false
    }
  ]
}

なお、スケジュール実行はis_enabledによって有効・無効を切り替えられます。デフォルトはfalse(スケジュール実行しない)ですので、有効にしたい場合はis_enabledtrueを指定してください。

設定値については、入出力リファレンスもあわせて参照してください。

Amazon EventBridgeを使ったイベントトリガー

Amazon S3

指定したAmazon S3バケット上のオブジェクトに変更があったことをトリガーにステートマシンを起動できます。

イベントはAWS CloudTrailの記録イベントで指定できます。たとえば、PutObjectGetObjectなどです。

指定できる値の詳細については、こちらをご覧ください。

また、こちらのチュートリアルもあわせてご参照ください。

ℹ️ Amazon S3バケット上のオブジェクトのイベントはAWS CloudTrail経由で検知します。 したがって、あらかじめAWS CloudTrailを有効にしておく必要があります。以下のリンク先の記述もあわせてご参照ください。

以下に設定例を示します。

module "step_functions" {
  ...
  s3_event_configs = [
    {
      bucket_name   = aws_s3_bucket.this.bucket
      events        = ["PutObject"]
      filter_prefix = null
    },
    {
      bucket_name   = aws_s3_bucket.this.bucket
      events        = ["PutObject"]
      filter_prefix = null
    }
  ]
}

filter_prefixを設定することで、イベントの検知対象とするオブジェクトの絞り込みが可能です。 こちらの記載もあわせて参照してください。

その他のイベントトリガー

上記以外のイベントによりステートマシンを起動したい場合は、イベントルールを個別に作成していただく必要があります。

以下に設定例を示します。

resource "aws_cloudwatch_event_rule" "rule" {
  name        = "..."
  description = "..."

  event_pattern = <<EOF
{
  <Step Functionsのトリガーとしたいイベントパターン>
}
EOF
}

resource "aws_cloudwatch_event_target" "step_functions" {
  rule      = aws_cloudwatch_event_rule.rule.name
  target_id = "SendToSNS" # 一意である必要があります。参考:https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target
  arn       = <Step FunctionsのARN>
}

イベントパターンの設定方法については以下のドキュメントを参照してください。

ステートマシンの監視・通知

ステートマシンのステータスについて

ステートマシンは、こちらにあるようなステータスで管理されています。

ステータスはマネジメントコンソールやAWS CLIから手動で確認できますが、ステータスの変化時にAmazon EventBridgeイベントを発行し、通知を送るような設定も可能です。

step_functions patternでは、SlackMicrosoft Teamsへの通知を設定可能です。

以下のドキュメントの記載もあわせて参照してください。

設定方法

通知先、通知タイミングについて

事前に、Slack、Microsoft TeamsのWebhook URLを取得しておいてください。

  • Slack/Microsoft Teamsのどちらかだけにも通知できますし、両方へも通知できます
  • ステータスに応じて、チャンネルをわけて通知できます

デフォルトでは、ステータスが変更された際はすべて通知を送るようになっています。どのステータスで通知を送るかはevent_pattern_statusで指定可能です。

ℹ️ 通知有無はslack_notification_configsteams_notification_configsの 設定有無により切替可能です。
通知を送りたくない場合は、これらの項目を設定しないようにしてください。

通知内容について

通知内容は入出力リファレンスinput_transformer_input_pathsinput_transformer_input_templateで編集できます。

イベントが送られてくると、以下の順で動作します。

  1. input_transformer_input_pathsを使って情報を取り出す
  2. input_transformer_input_templateのテンプレートに送られる
  3. 送信されるデータが作成される

設定内容については以下のリンク先を参照してください。

なお、nullを渡すと、Epona側で用意したプリセットが使用されます。

通知の設定例

slack_notification_configs =
[
  {
    webhook_uri                      = var.webhook_uri01
    input_transformer_input_paths    = null
    input_transformer_input_template = templatefile(
      "template.json", { color = "#00FF99" }
      )
    event_bus                        = "default"
    event_pattern_status             = ["SUCCEEDED"]
  },
  {
    webhook_uri                      = var.webhook_uri02
    input_transformer_input_paths    = null
    input_transformer_input_template = templatefile(
      "template.json", { color = "#0099FF" }
      )
    event_bus                        = "default"
    event_pattern_status             = ["RUNNING"]
  }
]

各ツールへの通知のサンプル

Slack

Slack

Microsoft Teams

Microsoft Teams

ステートマシン内の個々のステート(タスク)の監視・通知

複数のステートをつなげたステートマシンにおいて、どこのステートを実行していてもステートマシン全体としてはRUNNINGであり、「どこまで進んだか」といった状態は判断できません。

ステートマシン内の各ステート(タスク)の開始・完了を検知したい場合は、以下のような対応が必要です。

  • CloudWatch Logsからメトリクスを作る
  • 各タスク内でEventBridgeなどを利用する
  • EventBridgeやSNSを利用したタスクを挟む

ステートマシンのエラーハンドリング

処理中にエラーが発生した場合は、デフォルトではステートマシンの実行が失敗し停止します。
Catchステートや、Taskステート内のRetryを設定することでエラーハンドリングが可能です。

詳細はこちらを参照してください。

なお、実行が停止したステートマシンの、途中からの再実行はできません(新しく実行を開始すると先頭のステートから実行されます)。
ステートマシンの定義にあたっては、冪等性を意識した設計(たとえば、エラー終了時に途中状態をクリアするなど)となるようご留意ください。

ℹ️ こちら のブログ記事では、ステートマシン定義をコピーし、GoToStateステートにより任意のステートから実行する方法が紹介されています。必要に応じてご参照ください。

ステートマシンのログ

AWS Step Functionsの実行ログはAmazon CloudWatch Logsに保存されます。

ログに記録する対象をログレベルにより調整できます。これは入出力リファレンスlog_levelで設定できます。 ログレベルにはOFFALLERRORFATALがあり、このうち1つを指定します。デフォルトはALLです。

ℹ️ ログレベルをOFFにしても、ステートマシン用のロググループ自体は作成されます。

詳細についてはこちらを参照してください。

module "step_functions" {
  ..
  log_level                   = "ERROR"
}

サンプルコード

# スケジュールにより起動するステートマシンの例
module "step_functions" {
  source = "git::https://gitlab.com/eponas/epona.git//modules/aws/patterns/step_functions?ref=v0.2.6"

  sfn_name        = "YourStateMachineName"
  definition_json = file("your-definition.json")
  execution_resource_arns = [
    "arn:aws:lambda:ap-northeast-1:123456789012:function:SampleFunction:default" # Lambdaの場合の例。エイリアスでの管理が不要の場合は、エイリアス削除可
  ]

  enabled_xray                = true

  log_group_name              = "your-statemachine-log"
  log_level                   = "ALL"
  log_group_retention_in_days = 14

  schedule_configs = [
    {
      schedule_expression = "cron(0/5 * * ? *)"
      is_enabled          = true
    }
  ]
}

関連するpattern

step_functions_patternに関連するpatternを以下に記載します。

pattern名 説明
lambda Lambda関数を作成する

入出力リファレンス

Requirements

Name Version
terraform ~> 0.14.10
aws >= 3.44.0, < 4.0.0

Inputs

Name Description Type Default Required
definition_json Step Functionsの実行対象となる、ステートマシンのJSON定義を指定する。 string n/a yes
log_group_name ロググループの名前を指定する。 string n/a yes
sfn_name Step Functionsのステートマシンの名前を指定する。ロールなどのリソース名の編集にも使用している。文字数超過エラーが起きた場合は名称の長さを調整すること。 string n/a yes
enabled_xray X-Rayを利用するか指定する。デフォルトでは利用しない。 bool false no
execution_resource_arns ステートマシンのタスクが連携(統合)するAWSリソースのARNをリストで指定する。それにより、ステートマシンのIAM実行ロールに必要なIAMポリシーがアタッチされる。

対応しているAWSリソースは以下の通り。

- AWS Lambda関数
- Amazon Elastic Container Service(ECS)タスク
- Amazon Simple Notification Service(SNS)トピック
- Amazon Simple Queue Service(SQS)キュー

これら以外のAWSリソースを使用する場合は、利用者側で必要な権限を持ったIAMポリシーを作成し、ステートマシンの実行ロールにアタッチしていただく必要がある。
list(string) [] no
log_group_retention_in_days CloudWatch Logsにログを残す日数を指定する。デフォルトは14日間。 number 14 no
log_level CloudWatch Logsに書き出すログのログレベルとして、OFFALLERRORFATALのどれかを指定可能。
詳細はログレベルを参照のこと。デフォルトはALL
string "ALL" no
region Step Functionsのステートマシンを実行するリージョンを指定する。指定しなかった場合は、現在Terraformを実行中のリージョンが指定される。 string null no
s3_event_configs S3バケットのイベント経由でステートマシンを開始したい場合に指定する。

- bucket_name: ステートマシンを開始するトリガーとなるS3バケットの名前。(Required)
- events: ステートマシンを起動するS3イベント。イベントの種類はAWS CloudTrailのログ記録によって追跡されるAmazon S3オブジェクトレベルのアクションを参照。(Required)
- filter_prefix: S3バケット側のイベント発行の対象になるS3オブジェクトのプレフィックス。(Optional)

example:
s3_event_configs = [
{
bucket_name = YOUR_BUCKET_NAME
events = ["PutObject"]
filter_prefix = "prefix"
},
]
list(any) [] no
schedule_configs EeventBridgeのスケジュールを使ってステートマシンを開始したい場合に指定する。

schedule_expression にはスケジュールをrate()cron()で指定する。
記載方法はRateまたはCronを使用したスケジュール式を参照。

is_enabledtrueの時はスケジューリングを有効にする。デフォルトはfalse

example:
schedule_configs = [
{
schedule_expression = "rate(5 minutes)"
is_enabled = true
},
{
schedule_expression = "cron(0/5 * ? )"
is_enabled = false
}

]
list(any) [] no
slack_notification_configs 本設定があった場合はSlackに対して通知を行う。詳細はstep_functions patternの「通知」を参照。

example:
slack_notification_configs = [
{
webhook_uri = "https://webhook.example.com/webhook"
input_transformer_input_paths = null
input_transformer_input_template = null
event_bus = "default"
event_pattern_status = ["SUCCEEDED"]
},
webhook_uri = "https://another-webhook.example.com/webhook"
input_transformer_input_paths = null
input_transformer_input_template = null
event_bus = "default"
event_pattern_status = ["RUNNING"]
}
]
list(any) [] no
tags タグを指定する。 map(string) {} no
teams_notification_configs 本設定があった場合はMicrosoft Teamsに対して通知を行う。詳細はstep_functions patternの「通知」を参照。

example:
teams_notification_configs = [
{
webhook_uri = "https://webhook.example.com/webhook"
input_transformer_input_paths = null
input_transformer_input_template = null
event_bus = "default"
event_pattern_status = ["SUCCEEDED"]
},
webhook_uri = "https://another-webhook.example.com/webhook"
input_transformer_input_paths = null
input_transformer_input_template = null
event_bus = "default"
event_pattern_status = ["RUNNING"]
}
]
list(any) [] no

Outputs

Name Description
arn Step FunctionsのステートマシンのARN。
role_arn Step Functionsのステートマシンを実行するロールのARN。
role_name Step Functionsのステートマシンを実行するロールの名前を返す。

※ このドキュメントはクリエイティブコモンズ(Creative Commons) 4.0 の「表示—継承」に準拠しています。

※ このドキュメントに記載されている会社名、製品名は、各社の登録商標または商標です。

© 2021 TIS Inc.