この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
AWS Step Functionsを使ったタスクタイマーを10分でプロビジョンするチュートリアルが追加されていたため、実際にやってみました。
ステートマシン
Wait ステートを使って一定時間待機し、Task ステートを使って SNS に通知する Lambda を呼び出します。
最終的には以下のような AWS リソースがプロビジョンされます。
やってみた
以下の手順でサンプルプロジェクトを実行します。
- タスクタイマーをプロビジョン
- SNS の通知先を設定
- 実行
- 後片付け
1. タスクタイマーをプロビジョン
Step Function のダッシュボードから ”Create a state machine”を選択します
Sample Projects -> Task Timer を選択し、"Create Sample Project" ボタンをクリックします。
CloudFormation でリソースが作成される旨のメッセージが表示されます。 "Create Resources" ボタンをクリックします。
リソースの作成が始まります。
リソースの作成が完了すると、ステートマシーンを実行する "New execution" のダイアログが表示されます。
Input の JSON において
topic
はメッセージ送信先 SNS トピックmessage
はトピックに送信するメッセージtimer_seconds
は待機する秒数
を表します。
"Start execution" ボタンをクリックして、ステートマシーンを実行します。
ステートマシーンが実行されます。
ログを確認すると ExecutionStarted
タイプから WaitStateEntered
に遷移し、Input の timer_seconds
で指定した秒数だけ待機したあと(WaitStateExited
)、Lambda 関数を呼び出している(LambdaFunctionStarted)ことがわかります。
待機時間は WaitStateEntered
と WaitStateExited
の Elapsed Time(ms) の差分からわかります。
2. SNS の通知先を設定
このステートマシーンの実行が成功すると、 SNS トピックに通知されるのですが、デフォルトではこのトピックには何も購読していていないため、トピックに送信されたメッセージを受け取れません。 Email など確認しやすいプロトコルで購読しましょう。
3. 実行
トピックを追加したところでもう一度ステートマシーンを実行します。
Step Functions の Dashboard から作成されたステートマシーン(TaskTimerStateMachine-XXX
のような名前)を選択します。
次に "New execution" ボタンからステートマシンを実行します。
Input には 先程と同じ属性の JSON を指定します。
sample input
{
"topic": "arn:aws:sns:REGION:123456789012:XXX",
"message": "HelloWorld",
"timer_seconds": 10
}
”Start Execution” で実行します。
手順2において、トピックを Email-JSON で購読した場合、以下のようなメールが届きます。
{
"Type" : "Notification",
"MessageId" : "xxx",
"TopicArn" : "arn:aws:sns:ap-northeast-1:123456789012:StepFunctionsSample-TaskTimer-DUMMY",
"Message" : "task timer sample project",
"Timestamp" : "2018-03-02T21:46:19.798Z",
"SignatureVersion" : "1",
"Signature" : "DUMMY==",
"SigningCertURL" : "https://DUMMY",
"UnsubscribeURL" : "https://DUMMY"
}
4. 後片付け
このステートマシーンに関するリソースは全て CloudFormation で作成されています。
CloudFormation のスタック一覧に"StepFunctionsSample-TaskTimer-XXX" のスタック名が存在するため、削除しましょう。
プロビジョン内容を確認
プロビジョニングには CloudFormation を利用しています。 作成されたリソースを確認してみましょう。
作成されたリソース
CloudFormation により以下のリソースが作成されます。
- Step Functions : TaskTimerStateMachine
- SNS : SNSTopic
- Lambda : SendToSNS
- IAM Role : LambdaExecutionRole
- IAM Role : StatesExecutionRole
※ 論理ID
Step Functions : TaskTimerStateMachine はメインとなるステートマシーンです。
作成されるステートマシーンの Amazon States Language は以下です。
{
"Comment": "A Task Timer example of the Amazon States Language scheduling a task",
"StartAt": "Wait for Timestamp",
"States": {
"Wait for Timestamp": {
"Type": "Wait",
"SecondsPath": "$.timer_seconds",
"Next": "Send SNS Message"
},
"Send SNS Message": {
"Type": "Task",
"Resource": "arn:aws:lambda:ap-northeast-1:1234567890:function:StepFunctionsSample-TaskTimer-XXX",
"Retry" : [
{
"ErrorEquals": [ "States.ALL" ],
"IntervalSeconds": 1,
"MaxAttempts": 3,
"BackoffRate": 2.0
}
],
"End": true
}
}
}
Task ステートで Lambda を呼び出せるように、StatesExecutionRole ロールをアタッチしています。
StatesExecutionPolicy
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"lambda:InvokeFunction"
],
"Resource": "*",
"Effect": "Allow"
}
]
}
Lambda 関数 SendToSNS は指定された SNS トピックにメッセージ送信するだけのシンプルなものです。 Input から、メッセージ送信先トピックとメッセージを取得しています。
SendToSNS
console.log('Loading function');
const aws = require('aws-sdk');
exports.lambda_handler = (event, context, callback) => {
const sns = new aws.SNS();
console.log(`Sending message to SNS topic ${event.topic}`);
const messageInfo = {
Message: event.message,
TopicArn: event.topic
};
sns.publish(messageInfo, (err, data) => {
if (err) {
console.error(err.message);
callback(err.message);
return;
}
console.log(data);
callback(null);
});
};
SNS にメッセージ送信できるように、 LambdaExecutionRole ロールをアタッチしています。
LambdaExecutionRole
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"SNS:Publish"
],
"Resource": "arn:aws:sns:ap-northeast-1:123456789012:StepFunctionsSample-TaskTimer-XXX",
"Effect": "Allow"
}
]
}
最後に
Document History によると、このサンプルプロジェクトは既存のチュートリアルをより試しやすいように CloudFormation 化して 2018/01/18 に追加されたようです。
Step Functions はステートを定義するだけではほぼ何もやれず、タスクなどと連携して初めてまともに動作します。
今回のプロジェクトをサクッと起動すると、あとは Lambda 関数をいじるだけでミニマムなオレオレタスクタイマーの完成です。