AWS再入門ブログリレー AWS Step Functions 編

はじめに

当エントリは弊社コンサルティング部による『AWS再入門ブログリレー 2019』の5日目のエントリです。

昨日はかずえによる「Amazon DocumentDB」でした。

このブログリレーの企画は、普段AWSサービスについて最新のネタ・深い/細かいテーマを主に書き連ねてきたメンバーの手によって、 今一度初心に返って、基本的な部分を見つめ直してみよう、解説してみようというコンセプトが含まれています。

AWSをこれから学ぼう!という方にとっては文字通りの入門記事として、またすでにAWSを活用されている方にとってもAWSサービスの再発見や2019年のサービスアップデートのキャッチアップの場となればと考えておりますので、ぜひ最後までお付合い頂ければ幸いです。

本日5日目のテーマは『AWS Step Functions』です。

「ブラックベルト」および「FAQ」を元に、基本的な仕組みおよび使い方を紹介できればと思います。

目次

Step Functionsとは?

簡単に言えば、細分化された(した)機能を連結させて、視覚的に設計ができるマネージドサービスです。

AWS Lambda や Amazon ECS、自身で定義したサービスなどをどのように実行するかを設計できるジョブ管理のようなサービスです。

stepfunctions-image

上記フロー図の各進行先を『ステート』と称し、各ステートにおいてサービスの実行などを行います。

(なお、このステートがまとまったものを『ステートマシン』と呼びます。)

マネージドサービスなので、アプリケーションのコンポーネントとなる一連のステップは自動的にトリガーおよび追跡され、記録などをAmazonが行ってくれるため、アプリケーション開発を容易にしてくれます。

Step Functionsのメリット

  • アプリケーションを簡単に構築し、アプリケーションが意図したとおりに動作するように各ステップの実行を視覚化および追跡できる。

  • アプリケーションを構成する関数全体を管理するための余分なコーディングが不要になる。

  • 耐久性の向上。各ステップの状態を追跡し、リトライやロールバックによりエラーに対応できる。

要するに、疎結合化された各ステップ(サービスコンポーネント)から構成されるアプリケーションは、障害やスケーリングなどの変化にスピーディかつ柔軟に対応できるということです。変化に対してスピーディで柔軟であるということは、ビジネス上での競争力につながります。

Step Functionsのユースケース

ユースケースについては、1つ1つの処理を監査したい複数の処理を組み合わせたアプリケーションが利用検討対象かと思います。

AWSの類似サービスとの使い分け

Amazon Simple Queue Service (SQS)

  • アプリケーション内のすべてのサービス(タスク)とイベントのトラッキングを行いたい場合

=> Step Functions

  • サービス間でのメッセージ管理に、スケーラブルで信頼性の高いキューが必要な場合

=> SQS

Amazon Simple Workflow Service (SWF)

  • 基本的に今後の開発はStep Functionsを選択することを推奨。

  • プロセスにおいて介入する外部信号が必要な場合、または結果を親に返す子プロセスを起動する場合

=> SWF

利用するための主要な設計項目

利用するための、主要な設計項目を下記表にまとめます。

設計項目 役割 利用方法/対象
ステートマシン ステート全体をオーケストレートする単位。構成される要素はステートと呼ぶ。「ワークフロー」として可視化できる。 ASL (Amazon States Language) と呼ばれる JSON形式の言語
呼び出し元 ステートマシンを呼び出す方法。 マネジメントコンソール,CloudWatch Events,API Gateway,AWS CLIなど
呼び出し可能なサービス ステートマシンが実行できるサービス。 Lambda,DynamoDB,ECS/Fargate,Glue,Batchなど (その他、自身で定義したサービスを紐付けることも可能)
データの入出力 ステート間でのデータの受け渡しを指定する。 InputPath,Parameters,ResultPath,OutputPath
7つのステートタイプ 各ステートでどんな処理をするか。 Task,Wait,Pass,Parallel,Choice,Fail,Succeed
実行状況・パフォーマンスの確認 ステートごとの実行状況、結果や履歴などを確認できる。 マネジメントコンソール,CloudWatch Events,CloudWatchなど

詳細については、下記が詳しい(分かりやすい)のでこちらをご参考下さい。

料金について

料金 (2019/07/05 時点) AWS Step Functions の料金

  • 毎月 4,000 回までの状態遷移は無料 (12ヶ月間のAWS無料利用枠の期間とは別に)

  • 状態遷移 1,000 回あたり $0.025 (Tokyo Region)

やってみる

当エントリでは、実行タスクはシンプルにして、ステートタイプに焦点を当ててみようと思います。

出来るだけいろいろなステートを交えて、こんなのを作ってみます。

sfn sample-image

複雑に見えますが、意外と簡単に作成できます。

やっていること

  1. x,y,chanceの3つの数値を入力する。
  2. xとyの大きさを比較する。
  3. xの方がyより小さい場合、xに+1するが、チャンスは3回まで。3回のチャンスでもyが大きい場合は失敗。
  4. 3回のチャンス内でxがy以上なら足し算と引き算を並列に演算する。
  5. 3秒待たせる。
  6. 計算結果を出す。
  • 呼び出し元: Step Functions
  • 実行サービス: Lambda
  • データの入力: x,y,chanceの3つの数値データ
  • データの出力: 入力値から計算された和と差、チャンスの回数

4つLambda関数を作成します。

xとyの大小判定

 
# JadgeState
def lambda_handler(event, context):
    if event['x'] < event['y']:
        print("error")
        return 1
    return 0

チャンス

 
# AddOrg
def lambda_handler(event, context):
    event['x'] = event['x']+1
    event['chance'] = event['chance']+1
    return event

足し算

# AddState
def lambda_handler(event, context):
    return event['x'] + event['y'] 

引き算

 
# SubtractState
def lambda_handler(event, context):
    return event['x'] - event['y'] 

ステートマシンを作成します。

先ほど作成したLambdaのarnをステートに合わせて入力します。

 
# DemoArithmeticOperations
{
  "Comment": "An example of the Amazon States Language using various states.",
  "StartAt": "JadgeState",
  "States": {
    "JadgeState": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:1234567890:function:Jadge",
      "ResultPath": "$.res",
      "Next": "ChoiceState"
    },
    "ChoiceState": {
      "Type" : "Choice",
      "Choices": [
        {
        "And": [
        {
          "Variable": "$.res",
          "NumericEquals": 0
        },
        {
          "Variable": "$.chance",
          "NumericLessThanEquals": 3
        }
      ],
      "Next": "ArithmeticOperations"
      },
        {
        "And": [
        {
          "Variable": "$.res",
          "NumericEquals": 1
        },
        {
          "Variable": "$.chance",
          "NumericLessThanEquals": 3
        }
      ],
      "Next": "AddOrg"
      }
        ],
      "Default": "FailState"
    },
    "ArithmeticOperations": {
      "Type": "Parallel",
      "Next": "WaitState",
      "Branches": [
        {
         "StartAt": "AddState",
         "States": {
           "AddState": {
             "Type": "Task",
             "Resource":
             "arn:aws:lambda:ap-northeast-1:1234567890:function:Add",
             "ResultPath":"$.add",
             "OutputPath":"$.add",
             "End": true
           }
         }
       },
       {
        "StartAt": "SubtractState",
        "States": {
          "SubtractState": {
            "Type": "Task",
            "Resource":
            "arn:aws:lambda:ap-northeast-1:1234567890:function:Subtract",
            "ResultPath":"$.subtract",
             "OutputPath":"$.subtract",
            "End": true
          }
        }
      }
      ]
    },
    "AddOrg": {
      "Type" : "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:1234567890:function:AddOrg",
      "ResultPath": "$",
      "Next": "JadgeState"
    },
    "FailState": {
      "Type": "Fail",
      "Error": "FailStateError",
      "Cause": "Make x bigger!"
    },
    "WaitState": {
      "Type": "Wait",
      "Seconds": 3,
      "End": true
    }
  }
}

数値を適当に入れて実行してみます。

(ちなみに、文字列を入力すると怒られます。)

 
# Input
{
  "x": 3,
  "y": 4,
  "chance": 0
}
# Output
[8,0]

いかがでしょうか。

非常に簡単な例なのですが、ステートマシンの雰囲気はつかめたかと思います。

月並みな意見ですが、1度にまとめて作成するのでなく、順に1つずつステップを増やしていくと良いかと思います。

その上で、データの入出力がキモになるかと思います。

合わせて読みたい

Step Functions LocalとLocalStackを利用してローカル開発環境を構築してみた

Stepで覚えるStepFunctions基本のキ

最後に

以上、AWS再入門ブログリレー 5日目のエントリ『AWS Step Functions』編でした。

週明け月曜日(7/8)は坂巻一義の『Amazon QuickSight』編です。

お楽しみに!

参考/紹介

20190522 AWS Black Belt Online Seminar AWS Step Functions

AWS Step Functions のよくある質問

AWS Step Functions のドキュメント