AWS Step Functionsを定期的に実行するLambda関数をServerless Frameworkでデプロイする #reinvent
はじめに
2017年2月16日追記 API Gateway経由でStep Functionsが呼び出せるようになったようです。
2017年4月1日追記 AWSのアップデートによりCloudWatch EventsでStep Functionsを呼び出せるようになりました。
こんにちは、中山です。
AWS re:Invent 2016で発表されたAWS Step Functions。複数のAWSリソースをまとめてビジュアライズなワークフローで管理できる大変便利なサービスです。ただし現時点(2016/12/18)ではこのStep FunctionsをAWS上の何らかのイベント経由で実行することはサポートされていません。自分自身で呼び出す必要があります。いずれこの機能が提供されると思いますが、 現状どこからStep Functionsを実行するか は多くの方が課題だと感じているかと思います。今回はCloudWatch Eventsにより定期実行されたLambda関数からStep Functionsを実行する方法をご紹介します。Lambda関数のデプロイにはServerless Frameworkを利用します。
今回Lambda関数のコードではboto3を利用していますが、Step Functionsとboto3の利用方法については以下のエントリが参考になります。
やってみる
まずは以下のようなStep Functionsから呼び出されるLambda関数とServerless Frameworkの設定ファイルを用意してください。
invoked.py
from __future__ import print_function def handler(event, context): print(event) return event
serverless.yml
service: invoke-step-functions provider: name: aws runtime: python2.7 stage: dev region: ap-northeast-1 functions: invoked: handler: invoked.handler
sls
コマンドを利用してデプロイします。
$ sls deploy -v Serverless: Creating Stack... Serverless: Checking Stack create progress... <snip>
今回ステートマシンの作成はマネジメントコンソールで用意されている「Hello World」ブループリントを利用します。ステートマシン用JSONファイルの Resource
に先程デプロイしたLambda関数のARNを指定してください。ARNは sls info
で確認できます。
続いて作成したStep Functionsを呼び出すLambda関数をデプロイします。以下のコードを用意してください。
invoke.py
from __future__ import print_function import os import boto3 client = boto3.client('stepfunctions') def handler(event, context): resp = client.start_execution( **{ 'input': '{"Comment": "Test"}', 'stateMachineArn': os.environ['stateMachineArn'] } ) print(resp)
このLambda関数をデプロイするために先程の serverless.yml
を以下のように変更してください。環境変数に渡している stateMachineArn
は aws stepfunctions list-state-machines
などで確認できます。
service: invoke-step-functions provider: name: aws runtime: python2.7 stage: dev region: ap-northeast-1 custom: stateMachineArn: arn:aws:states:ap-northeast-1:************:stateMachine:test functions: invoke: handler: invoke.handler role: StepFunctionsExecRole environment: stateMachineArn: ${self:custom.stateMachineArn} events: - schedule: rate(1 minute) invoked: handler: invoked.handler resources: Resources: StepFunctionsExecRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Sid: StsAssumeRole Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Policies: - PolicyName: StartExecution PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - states:StartExecution Resource: ${self:custom.stateMachineArn}
デプロイします。
$ sls deploy -v Serverless: Packaging service... Serverless: Uploading CloudFormation file to S3... Serverless: Uploading service .zip file to S3 (1005 B)... Serverless: Updating Stack... Serverless: Checking Stack update progress... <snip>
今回は1分毎にStep Functionsを呼び出すLambda関数を実行させているため以下のコマンドでログを出力させ続けてみます。
$ sls logs -f invoke -t START RequestId: 05e0d449-c51e-11e6-8034-7101556b1caf Version: $LATEST {u'startDate': datetime.datetime(2016, 12, 18, 12, 35, 21, 16000, tzinfo=tzlocal()), 'ResponseMetadata': {'RetryAttempts': 0, 'HTTPStatusCode': 200, 'RequestId': '708899f9-c51e-11e6-a401-df8361e4a81c', 'HTTPHeaders': {'x-amzn-requestid': '708899f9-c51e-11e6-a401-df8361e4a81c', 'content-length': '142', 'content-type': 'application/x-amz-json-1.0'}}, u'executionArn': u'arn:aws:states:ap-northeast-1:************:execution:test:d997224c-761b-46da-a535-d7d336dd03c1'} END RequestId: 05e0d449-c51e-11e6-8034-7101556b1caf REPORT RequestId: 05e0d449-c51e-11e6-8034-7101556b1caf Duration: 247.52 ms Billed Duration: 300 ms Memory Size: 1024 MB Max Memory Used: 18 MB START RequestId: 70f58c68-c51e-11e6-97f0-473036194eb9 Version: $LATEST {u'startDate': datetime.datetime(2016, 12, 18, 12, 35, 21, 834000, tzinfo=tzlocal()), 'ResponseMetadata': {'RetryAttempts': 0, 'HTTPStatusCode': 200, 'RequestId': '7106557e-c51e-11e6-a401-df8361e4a81c', 'HTTPHeaders': {'x-amzn-requestid': '7106557e-c51e-11e6-a401-df8361e4a81c', 'content-length': '142', 'content-type': 'application/x-amz-json-1.0'}}, u'executionArn': u'arn:aws:states:ap-northeast-1:************:execution:test:1daee69e-8ab3-4ba2-9f30-43afbec3fe30'} END RequestId: 70f58c68-c51e-11e6-97f0-473036194eb9 REPORT RequestId: 70f58c68-c51e-11e6-97f0-473036194eb9 Duration: 232.96 ms Billed Duration: 300 ms Memory Size: 1024 MB Max Memory Used: 18 MB <snip>
正常に実行されているようです。Step Functionsから呼び出されるLambda関数の様子も見てみます。
$ sls logs -f invoked -t START RequestId: b9250285-c51e-11e6-923e-87aeefda4cc3 Version: $LATEST {u'Comment': u'Test'} END RequestId: b9250285-c51e-11e6-923e-87aeefda4cc3 REPORT RequestId: b9250285-c51e-11e6-923e-87aeefda4cc3 Duration: 0.35 ms Billed Duration: 100 ms Memory Size: 1024 MB Max Memory Used: 16 MB START RequestId: dcdc6238-c51e-11e6-91cb-0502066f89a6 Version: $LATEST {u'Comment': u'Test'} END RequestId: dcdc6238-c51e-11e6-91cb-0502066f89a6 REPORT RequestId: dcdc6238-c51e-11e6-91cb-0502066f89a6 Duration: 0.36 ms Billed Duration: 100 ms Memory Size: 1024 MB Max Memory Used: 16 MB <snip>
こちらも問題なさそうです。やりましたね。
まとめ
いかがだったでしょうか。
定期的に実行されるLambda関数からStep Functionsを呼び出してみました。AWSが公式にStep Functionsのイベントサポートまでのワークアラウンドですが、もし同じような問題を抱えている際は参考にしていただければと思います。
本エントリがみなさんの参考になったら幸いに思います。