SAMでAWS Step Functionsを試してみる
はじめに
Lambdaは使ったことあるのですが、StepFunctionを使ったことが無いので、サンプルプログラムで雰囲気をつかんでみたいと思います。
下記の公式チュートリアルも見つつ進めていきます。
実行環境
Step FunctionsはAWS SAM(Serverless Application Model)で作っていきます。
ランタイムはGoにします。
Goのバージョンは元々1.xだけだったのですが、いつの間にかprovided.al2
が出来ていました。
1.xは今年一杯で廃止予定のようなので、provided.al2
一択ですね。
事前準備
samコマンドで簡単にサーバレスアプリケーションの構成とビルド、デプロイができるので非常に便利です。
-
samコマンドを使うにはAWS CLIが必要なのでインストールします。
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html -
デプロイに必要な権限を割り当てておく
デプロイ時は、CloudFormationによってデプロイが実施されます。
デプロイを実行する権限は、credentialsに定義されたアカウントを指定しますが、
そのアカウントにデプロイ時に必要な権限が揃っていないと途中でエラーになります。
環境設定
sam init
で対話式でテンプレートのセットアップができます。
- AWS Quick Start Templates
1 - AWS Quick Start Templates - Choose an AWS Quick Start application template
4 - Multi-step workflow - Which runtime would you like to use?
3 - go (provided.al2) - 他はデフォルトでOK
- 最後にプロジェクト名を聞かれるので、
sam-step-function-sample
としました。
Project name [sam-app]: sam-step-function-sample
$ sam init
You can preselect a particular runtime or package type when using the `sam init` experience.
Call `sam init --help` to learn more.
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1
Choose an AWS Quick Start application template
1 - Hello World Example
2 - Data processing
3 - Hello World Example with Powertools for AWS Lambda
4 - Multi-step workflow
5 - Scheduled task
6 - Standalone function
7 - Serverless API
8 - Infrastructure event management
9 - Lambda Response Streaming
10 - Serverless Connector Hello World Example
11 - Multi-step workflow with Connectors
12 - GraphQLApi Hello World Example
13 - Full Stack
14 - Lambda EFS example
15 - Hello World Example With Powertools for AWS Lambda
16 - DynamoDB Example
17 - Machine Learning
Template: 4
Which runtime would you like to use?
1 - dotnet6
2 - go1.x
3 - go (provided.al2)
4 - java17
5 - java11
6 - java8.al2
7 - java8
8 - nodejs18.x
9 - nodejs16.x
10 - nodejs14.x
11 - python3.9
12 - python3.8
13 - python3.7
14 - python3.11
15 - python3.10
16 - ruby3.2
17 - ruby2.7
Runtime: 3
Based on your selections, the only Package type available is Zip.
We will proceed to selecting the Package type as Zip.
Based on your selections, the only dependency manager available is mod.
We will proceed copying the template using mod.
Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]:
Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]:
Project name [sam-app]: sam-step-function-sample
-----------------------
Generating application:
-----------------------
Name: sam-step-function-sample
Runtime: go (provided.al2)
Architectures: x86_64
Dependency Manager: mod
Application Template: step-functions-sample-app
Output Directory: .
Configuration file: sam-step-function-sample/samconfig.toml
Next steps can be found in the README file at sam-step-function-sample/README.md
Commands you can use next
=========================
[*] Create pipeline: cd sam-step-function-sample && sam pipeline init --bootstrap
[*] Validate SAM template: cd sam-step-function-sample && sam validate
[*] Test Function in the Cloud: cd sam-step-function-sample && sam sync --stack-name {stack-name} --watch
コマンドを実行したディレクトリに先ほど指定したプロジェクト名でディレクトリが作成されます。
出来上がったディレクトリ構成
sam-step-function-sample
├── Makefile
├── README.md
├── functions
│ ├── stockBuyer
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── main.go
│ │ └── main_test.go
│ ├── stockChecker
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── main.go
│ │ └── main_test.go
│ └── stockSeller
│ ├── go.mod
│ ├── go.sum
│ ├── main.go
│ └── main_test.go
├── samconfig.toml
├── statemachine
│ └── stockTrader.asl.json
└── template.yaml
- functions・・・lambda関数の実装が入っています。
- samconfig.toml・・・デプロイ時に使用する設定ファイルです。
- statemachine・・・ステートマシーンの定義ファイルが入っています。
- template.yaml・・・SAMでデプロイされるlambda等のリソース定義が入っています。
ビルド
$ sam build
Starting Build use cache
Cache is invalid, running build and copying resources for following functions (StockCheckerFunction)
Building codeuri: /path/to/directory/sam-step-function-sample/functions/stockChecker runtime: provided.al2 metadata: {'BuildMethod': 'go1.x'} architecture: x86_64 functions:
StockCheckerFunction
Cache is invalid, running build and copying resources for following functions (StockBuyerFunction)
Cache is invalid, running build and copying resources for following functions (StockSellerFunction)
Building codeuri: /path/to/directory/sam-step-function-sample/functions/stockBuyer runtime: provided.al2 metadata: {'BuildMethod': 'go1.x'} architecture: x86_64 functions:
StockBuyerFunction
Building codeuri: /path/to/directory/sam-step-function-sample/functions/stockSeller runtime: provided.al2 metadata: {'BuildMethod': 'go1.x'} architecture: x86_64 functions:
StockSellerFunction
Running GoModulesBuilder:Build
Running GoModulesBuilder:Build
Running GoModulesBuilder:Build
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
デプロイ
デプロイします。
※ログは適度に余分なスペースを取り除いてます。
$ sam deploy --guided
Configuring SAM deploy
======================
Looking for config file [samconfig.toml]: Found
Reading default arguments : Success
Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-step-function-sample]:
AWS Region [ap-northeast-1]:
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [Y/n]:
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]:
#Preserves the state of previously provisioned resources when an operation fails
Disable rollback [y/N]:
Save arguments to configuration file [Y/n]:
SAM configuration file [samconfig.toml]:
SAM configuration environment [default]:
Looking for resources needed for deployment:
Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-1491q9q7zj9a6
A different default S3 bucket can be set in samconfig.toml and auto resolution of buckets turned off by setting resolve_s3=False
Parameter "stack_name=sam-step-function-sample" in [default.deploy.parameters] is defined as a global parameter [default.global.parameters].
This parameter will be only saved under [default.global.parameters] in /path/to/directory/sam-step-function-sample/samconfig.toml.
Saved arguments to config file
Running 'sam deploy' for future deployments will use the parameters saved above.
The above parameters can be changed by modifying samconfig.toml
Learn more about samconfig.toml syntax at
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html
Deploying with following values
===============================
Stack name : sam-step-function-sample
Region : ap-northeast-1
Confirm changeset : True
Disable rollback : False
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-1491q9q7zj9a6
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Signing Profiles : {}
Initiating deployment
=====================
Waiting for changeset to be created..
CloudFormation stack changeset
----------------------------------------------------------------------------
Operation LogicalResourceId ResourceType Replacement
----------------------------------------------------------------------------
+ Add StockBuyerFunctionRole AWS::IAM::Role N/A
+ Add StockBuyerFunction AWS::Lambda::Function N/A
+ Add StockCheckerFunctionRole AWS::IAM::Role N/A
+ Add StockCheckerFunction AWS::Lambda::Function N/A
+ Add StockSellerFunctionRole AWS::IAM::Role N/A
+ Add StockSellerFunction AWS::Lambda::Function N/A
+ Add StockTradingStateMachineHourlyTradingScheduleRole AWS::IAM::Role N/A
+ Add StockTradingStateMachineHourlyTradingSchedule AWS::Events::Rule N/A
+ Add StockTradingStateMachineRole AWS::IAM::Role N/A
+ Add StockTradingStateMachine AWS::StepFunctions::StateMachine N/A
+ Add TransactionTable AWS::DynamoDB::Table N/A
〜〜〜 中略 〜〜〜
Successfully created/updated stack - sam-step-function-sample in ap-northeast-1
途中CloudFormationでの進捗状況が出力されます。
完了した分のログのみ抽出すると以下のようになっています。
これらがデプロイによって作成されたリソースとなっています。
CloudFormation events from stack operations (refresh every 5.0 seconds)
----------------------------------------------------------------------
ResourceStatus ResourceType LogicalResourceId ResourceStatusReason
----------------------------------------------------------------------
CREATE_COMPLETE AWS::DynamoDB::Table TransactionTable -
CREATE_COMPLETE AWS::IAM::Role StockCheckerFunctionRole -
CREATE_COMPLETE AWS::IAM::Role StockBuyerFunctionRole -
CREATE_COMPLETE AWS::IAM::Role StockSellerFunctionRole -
CREATE_COMPLETE AWS::Lambda::Function StockBuyerFunction -
CREATE_COMPLETE AWS::Lambda::Function StockCheckerFunction -
CREATE_COMPLETE AWS::Lambda::Function StockSellerFunction -
CREATE_COMPLETE AWS::IAM::Role StockTradingStateMachineRole -
CREATE_COMPLETE AWS::StepFunctions::StateMachine StockTradingStateMachine -
CREATE_COMPLETE AWS::IAM::Role StockTradingStateMachineHourlyTradingScheduleRole -
CREATE_COMPLETE AWS::Events::Rule StockTradingStateMachineHourlyTradingSchedule -
CREATE_COMPLETE AWS::CloudFormation::Stack sam-step-function-sample -
作成されたリソースの確認
cloud formation
lambda
作成されたlambdaはアプリケーションとしてまとめられて作成されています。
Step Functions
真ん中のフローチャートのような図がワークフローと言う、何が動作するかがなんとなく分かる図になっています。
それぞれの四角がステートといわれ、lambdaだったり判断条件だったりが設定できるようです。
DBもステートとして設定できるのもすごいですね。
ステートとステートの繋がりは次のステートを何にするかを指定することで設定します。
json定義
{
"Comment": "A state machine that does mock stock trading.",
"StartAt": "Check Stock Value",
"States": {
"Check Stock Value": {
"Type": "Task",
"Resource": "arn:aws:lambda:ap-northeast-1:214536320901:function:sam-step-function-sample-StockCheckerFunction-qHTfdO2NslqG",
"Retry": [
{
"ErrorEquals": [
"States.TaskFailed"
],
"IntervalSeconds": 15,
"MaxAttempts": 5,
"BackoffRate": 1.5
}
],
"Next": "Buy or Sell?"
},
"Buy or Sell?": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.stockPrice",
"NumericLessThanEquals": 50,
"Next": "Buy Stock"
}
],
"Default": "Sell Stock"
},
"Sell Stock": {
"Type": "Task",
"Resource": "arn:aws:lambda:ap-northeast-1:214536320901:function:sam-step-function-sample-StockSellerFunction-1XygAt1w6ObC",
"Retry": [
{
"ErrorEquals": [
"States.TaskFailed"
],
"IntervalSeconds": 2,
"MaxAttempts": 3,
"BackoffRate": 1
}
],
"Next": "Record Transaction"
},
"Buy Stock": {
"Type": "Task",
"Resource": "arn:aws:lambda:ap-northeast-1:214536320901:function:sam-step-function-sample-StockBuyerFunction-B9IleRhw0Gqh",
"Retry": [
{
"ErrorEquals": [
"States.TaskFailed"
],
"IntervalSeconds": 2,
"MaxAttempts": 3,
"BackoffRate": 1
}
],
"Next": "Record Transaction"
},
"Record Transaction": {
"Type": "Task",
"Resource": "arn:aws:states:::dynamodb:putItem",
"Parameters": {
"TableName": "sam-step-function-sample-TransactionTable-1C4YWNMRDFRPA",
"Item": {
"Id": {
"S.$": "$.id"
},
"Type": {
"S.$": "$.transactionType"
},
"Price": {
"N.$": "$.price"
},
"Quantity": {
"N.$": "$.qty"
},
"Timestamp": {
"S.$": "$.timestamp"
}
}
},
"Retry": [
{
"ErrorEquals": [
"States.TaskFailed"
],
"IntervalSeconds": 20,
"MaxAttempts": 5,
"BackoffRate": 10
}
],
"End": true
}
}
}
ちなみに、コンソールでステートマシンを作ると
EventBridge
リソース見なかったら見逃してましたが、
1時間おきの起動でスケジューラが作成されていました。
ただ、テンプレートだからなのか、有効化はされていないので、勝手に動き出すということは無いようです。
DynamoDB
上記以外にこれらのリソースを統合するための権限も作られています。
テスト
テストはステートマシーンの実行で行います。
「実行を開始」をクリックし、
入力はデフォルトのままいってみます。
成功です!
通過したところが分かるのと、成功失敗も分かりそうです。
緑の箇所をクリックすると、右側に実行された際の入力や出力、詳細情報が確認できます。
というわけで、無事動作確認までできました。
おわりに
SAMで簡単にStep Functionsを作成することができました。
Step Functionsの肝はステートマシンの設定まわりだと思いますが、
このチュートリアルでできた設定を見ながら、感覚を掴んでいきたいと思いました。
今回作成したStep Functionのテンプレートは以下リポジトリで公開しています。
下記のリンクには他にもStep Functionsのチュートリアルがあるので、こちらも参考になると思います。
Discussion