はじめに
AWS::Serverless::StateMachine リソースを使用して、SAM テンプレート内で AWS Step Functions の
ステートマシンを定義できるようになりました。
AWS SAM adds support for AWS Step Functions
https://aws.amazon.com/jp/about-aws/whats-new/2020/05/aws-sam-adds-support-for-aws-step-functions/
AWS SAM CLI も v0.52.0 で Step Functions Resource をサポートしています。
Support for a new Step Functions Resource in SAM
https://github.com/awslabs/aws-sam-cli/releases/v0.52.0
やってみる
前述のとおり、AWS SAM CLI は v0.52.0 以上である必要があります。
$ sam --version
SAM CLI, version 0.52.0
ステートマシンの定義ファイルとSAM テンプレートを以下のように作成していきます。
sam-app
├── statemachine
│ └── putitem.asl.json
└── template.yaml
ステートマシンの定義
ここでは簡単な例を示すために AWS Step Functions のサービス統合を使用して
Input で受け取った内容をDynamoDB に保存するだけのステートマシンを作成します。
以下のようなシンプルな定義です。Lambda 関数すらありません。
Resource と TableName をプレースホルダ変数としているところに着目してください。
{
"StartAt": "PutDynamoDB",
"States": {
"PutDynamoDB": {
"Type": "Task",
"Resource": "${DDBPutItem}",
"Parameters": {
"TableName": "${DDBTable}",
"Item": {
"id": {"S.$": "$.id"},
"message": {"S.$": "$.message"}
}
},
"End": true
}
}
}
余談ですが、AWS Toolkit for Visual Studio を使用するとローカルでステートマシンの
グラフを描写できるので便利です。(今回は描写するまでもないんですが。。。)
参考: AWS Toolkit for Visual Studio Code が AWS Step Functions のサポートを開始
https://aws.amazon.com/jp/about-aws/whats-new/2020/03/aws-toolkit-for-visual-studio-code-supports-aws-step-functions/
SAM テンプレート
AWS::Serverless::StateMachine リソースを使用しています。
ステートマシンは Definition プロパティでテンプレート内に直接インラインで定義するか
以下のように DefinitionUri プロパティで定義ファイルを指定することができます。
更に DefinitionSubstitutions プロパティを使用することで、デプロイ時に取得した値を
先ほどのステートマシン定義に注入することができます。
また受け取ったデータを保存するための DynamoDB テーブルも定義しています。
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app
Sample SAM Template for Step Functions
Resources:
PutDynamoDBStateMachine:
Type: AWS::Serverless::StateMachine
Properties:
DefinitionUri: statemachine/putitem.asl.json
DefinitionSubstitutions:
DDBPutItem: !Sub arn:${AWS::Partition}:states:::dynamodb:putItem
DDBTable: !Ref Table
Policies:
- DynamoDBWritePolicy:
TableName: !Ref Table
Table:
Type: AWS::Serverless::SimpleTable
Properties:
PrimaryKey:
Name: id
Type: String
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
その他のプロパティについては以下のドキュメントを参照ください。
AWS::Serverless::StateMachine
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-statemachine.html
デプロイ & 結果確認
準備は以上で、あとはいつもどおりに sam deploy するだけです!
$ cd sap-app
$ sam deploy --guided
変更セットを確認して実行します。
Dynamo DB テーブルおよび ステートマシン、ステートマシン用のロールが作成されます。
CloudFormation stack changeset
-----------------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType
-----------------------------------------------------------------------------------------
+ Add PutDynamoDBStateMachineRole AWS::IAM::Role
+ Add PutDynamoDBStateMachine AWS::StepFunctions::StateMachine
+ Add Table AWS::DynamoDB::Table
-----------------------------------------------------------------------------------------
デプロイされたステートマシンを確認すると、SAM によって作成された DynamoDB テーブル名が
定義に反映されていることがわかります。
以下のような入力でステートマシンを実行します。
{
"id": "1",
"message": "Hello World"
}
API Gateway を追加する
Amazon API Gateway から 先ほどのステートマシンを実行できるように変更してみます。
SAM テンプレートの編集
AWS::Serverless::StateMachine のプロパティに以下を追加するだけです。SAM の本領発揮ですね。
Events:
HttpRequest:
Type: Api
Properties:
Method: POST
Path: /request
以下のようになります。
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app
Sample SAM Template for Step Functions
Resources:
PutDynamoDBStateMachine:
Type: AWS::Serverless::StateMachine
Properties:
DefinitionUri: statemachine/putitem.asl.json
DefinitionSubstitutions:
DDBPutItem: !Sub arn:${AWS::Partition}:states:::dynamodb:putItem
DDBTable: !Ref Table
Events:
HttpRequest:
Type: Api
Properties:
Method: POST
Path: /request
Policies:
- DynamoDBWritePolicy:
TableName: !Ref Table
Table:
Type: AWS::Serverless::SimpleTable
Properties:
PrimaryKey:
Name: id
Type: String
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
再度デプロイします。
$ sam deploy
変更セットを確認して実行します。API Gateway が追加されます。
CloudFormation stack changeset
-----------------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType
-----------------------------------------------------------------------------------------
+ Add PutDynamoDBStateMachineHttpRequestRole AWS::IAM::Role
+ Add ServerlessRestApiDeploymenta4c0d5c32b AWS::ApiGateway::Deployment
+ Add ServerlessRestApiProdStage AWS::ApiGateway::Stage
+ Add ServerlessRestApi AWS::ApiGateway::RestApi
-----------------------------------------------------------------------------------------
デプロイされた API の設定を確認すると、AWS Service Proxy で直接ステートマシンを実行するよう
構成されていることがわかります。
API に対して以下のような Post リクエストを送ります。
$ curl -X POST -d '{"input": "{\"id\": \"2\",\"message\": \"Work From Home\"}","name": "FromAPI","stateMachineArn": "arn:aws:states:ap-northeast-1:123456789012:stateMachine:PutDynamoDBStateMachine-xxxxxxxxxxxx"}' https://yyyyyyyyyy.execute-api.ap-northeast-1.amazonaws.com/Prod/request
{"executionArn":"arn:aws:states:ap-northeast-1:123456789012:execution:PutDynamoDBStateMachine-xxxxxxxxxxxx:FromAPI","startDate":1.590690379952E9}