この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
こんにちは、中山です。
米国時間2017/02/10、CloudFormation(以下CFn)がStep Functionsをサポートしました。今回導入されたリソースは以下の2つです。プロパティに指定可能な値はドキュメントを参照してください。
- AWS::StepFunctions::Activity
- Activitiyの作成
- AWS::StepFunctions::StateMachine
- State Machineの作成
早速使ってみたので本エントリでご紹介させていただきます。単純に使うだけだとあまり面白くないのでServerless Frameworkからこの機能を利用してみます。なお、Serverless FrameworkとStep Functionsの連携はプラグインを利用することでも実現可能です。ご興味があれば以下のエントリを参照してください。
本エントリを執筆する上で検証に利用した主要なツールのバージョンは以下の通りです。バージョンによって結果が変更される可能性があるので、その点ご了承ください。
- Serverless Framework: 1.6.1
使ってみる
以下のファイルを用意してください。
serverless.yml
service: aws-python
frameworkVersion: ">=1.6.0"
custom:
config: ${file(config.${opt:stage}.yml)}
provider:
name: aws
runtime: python2.7
stage: ${opt:stage}
region: ap-northeast-1
functions:
hello:
handler: handler.hello
resources: ${file(resource.yml)}
Serverless Frameworkは resources
プロパティでCFnテンプレートを指定できます。 serverless.yml
に直接記述することも可能ですが、上記のように ${file(path/to/template.yml)}
の形で別ファイルから読み込むことも可能です。
resource.yml
---
AWSTemplateFormatVersion: "2010-09-09"
Description: Step Functions Test
Resources:
InvokeLambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: StepFunctionsAssumeRolePolicy
Effect: Allow
Principal:
Service:
Fn::Join: [ ".", [ states, Ref: "AWS::Region", amazonaws, com ] ]
Action: sts:AssumeRole
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaRole
TestStateMachine:
Type: AWS::StepFunctions::StateMachine
Properties:
RoleArn:
Fn::GetAtt: [ InvokeLambdaRole, Arn ]
DefinitionString: |-
{
"StartAt": "HelloWorld",
"States": {
"HelloWorld": {
"Type": "Task",
"Resource": "arn:aws:lambda:${self:provider.region}:${self:custom.config.accountId}:function:${self:service}-${opt:stage}-hello",
"End": true
}
}
}
Outputs:
StateMachineArn:
Value:
Ref: TestStateMachine
StateMachineName:
Value:
Fn::GetAtt: [ TestStateMachine, Name ]
CFnテンプレートの内容は単純です。 AWS::Iam::Role
リソースでState Machine用のIAM Roleを作成し、 AWS::StepFunctions::StateMachine
でState Machineを作成しています。
AWS::StepFunctions::StateMachine
リソースでは DefinitionString
プロパティでAmazon State Languageを記述できます。 Task
に指定している Resource
にはServerless FrameworkでデプロイしたLambda関数のARNを指定する必要がるのですが、今回は各種値(リージョンやAWSアカウントIDなど)にServerless Frameworkの強力な変数展開機能を利用しました。もし、CFn単体でState Machineを作成するのであれば、以下のようにFn::Sub組み込み関数を利用してLambda関数のARNを取得するとよいと思います。
TestStateMachine:
Type: AWS::StepFunctions::StateMachine
Properties:
RoleArn: !GetAtt InvokeLambdaRole.Arn
DefinitionString: !Sub |-
{
"StartAt": "HelloWorld",
"States": {
"HelloWorld": {
"Type": "Task",
"Resource": "${SomeLambdaFunc.Arn}",
"End": true
}
}
}
なお、残念ながらServerless Framework 1.6.1時点ではCFnの組み込み関数の短縮機能がサポートされていないようです。また、例えば AWSTemplateFormatVersion: "2010-09-09"
の日付部分を引用符で囲まないとエラーが出てしまいます。恐らくCFnではなくServerless Framework独自のバリデーションがテンプレート作成の前に働いているのかと推測しますが、この辺りもう少し改善してほしいですね。
スタックの作成は以下のコマンドで実行します。今回は説明を省略しましたが、利用しているLambda関数は sls create
で出力されるテンプレートをそのまま使っています。
$ sls deploy -v -s dev
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
<snip>
スタックが作成されたらState Machineの動作を確認してみます。
- State Machineが作成されたことを確認
$ aws stepfunctions list-state-machines
{
"stateMachines": [
{
"creationDate": 1486760475.332,
"stateMachineArn": "arn:aws:states:ap-northeast-1:************:stateMachine:TestStateMachine-4VMKMDOODSCT",
"name": "TestStateMachine-4VMKMDOODSCT"
}
]
}
- State Machineの内容が意図したものになっていることを確認
$ aws stepfunctions describe-state-machine \
--state-machine-arn "$(aws stepfunctions list-state-machines \
--query 'stateMachines[?name==`TestStateMachine-4VMKMDOODSCT`].stateMachineArn' \
--output text)"
{
"status": "ACTIVE",
"definition": "{\n \"StartAt\": \"HelloWorld\",\n \"States\": {\n \"HelloWorld\": {\n \"Type\": \"Task\",\n \"Resource\":\"arn:aws:lambda:ap-northeast-1:************:function:aws-python-dev-hello\",\n \"End\": true\n }\n }\n}",
"name": "TestStateMachine-4VMKMDOODSCT",
"roleArn": "arn:aws:iam::************:role/aws-python-dev-InvokeLambdaRole-1P0ARBB2HRIS6",
"stateMachineArn": "arn:aws:states:ap-northeast-1:************:stateMachine:TestStateMachine-4VMKMDOODSCT",
"creationDate": 1486760475.332
}
- State Machineの実行
$ aws stepfunctions start-execution \
--state-machine-arn "$(aws stepfunctions list-state-machines \
--query 'stateMachines[?name==`TestStateMachine-4VMKMDOODSCT`].stateMachineArn' \
--output text)" \
--input "$(jo hoge=fuga)"
{
"startDate": 1486762893.681,
"executionArn": "arn:aws:states:ap-northeast-1:************:execution:TestStateMachine-4VMKMDOODSCT:d79f8996-07f1-493e-99c1-4a679ce97071"
}
- 実行結果が意図したものになったことを確認
$ aws stepfunctions describe-execution \
--execution-arn "arn:aws:states:ap-northeast-1:************:execution:TestStateMachine-4VMKMDOODSCT:d79f8996-07f1-493e-99c1-4a679ce97071"
{
"status": "SUCCEEDED",
"startDate": 1486762893.681,
"name": "d79f8996-07f1-493e-99c1-4a679ce97071",
"executionArn": "arn:aws:states:ap-northeast-1:************:execution:TestStateMachine-4VMKMDOODSCT:d79f8996-07f1-493e-99c1-4a679ce97071",
"stateMachineArn": "arn:aws:states:ap-northeast-1:************:stateMachine:TestStateMachine-4VMKMDOODSCT",
"stopDate": 1486762894.946,
"output": "{\"body\": \"{\\\"input\\\": {\\\"hoge\\\": \\\"fuga\\\"}, \\\"message\\\": \\\"Go Serverless v1.0! Your function executed successfully!\\\"}\", \"statusCode\": 200}",
"input": "{\"hoge\":\"fuga\"}"
}
まとめ
いかがだったでしょうか。
CloudFormationがStep Functionsをサポートした点、またServerless Frameworkからこの機能を利用する方法をご紹介しました。 DefinitionString
のYAMLサポート早く来てくれ!!!!1111
本エントリがみなさんの参考になれば幸いに思います。