この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、CX事業本部 IoT事業部の若槻です。
今回は、AWS Step FunctionsステートマシンでDynamoDBテーブルからアイテムを取得してMapステートで処理してみました。
作るもの
指定のエリアにいるクルーに次に移動するべきエリアを通知するアプリです。
やってみた
対象のDynamoDBテーブル
下記のクルーの現在位置と従業員情報を管理するDynamoDBテーブルをクエリ対象とします。
- テーブル名:
crews
- PK:
crewId
(String) - GSI名:
areaId-index
- GSI-PK:
areaId
(String)
格納されているデータは以下となります。
ステートマシンの作成
Step Functions Workflow Studioでステートマシンを作成します。
Step Functionsのマネジメントコンソールでステートマシンの作成を開始します。
[次へ]をクリックします。
[action]をquery
で検索して[DynamoDB Query]をドラッグします。
[Query]の[設定]で、[APIパラメータ]で下記のJSONを指定します。
{
"TableName": "crews",
"IndexName": "areaId-index",
"ExpressionAttributeNames": {
"#areaId": "areaId"
},
"ExpressionAttributeValues": {
":areaId": {
"S.$": "$.areaId"
}
},
"KeyConditionExpression": "#areaId = :areaId"
}
[Query]の[出力]で、[ResultSelector]と[ResultPath]を指定します。
- ResultSelector
{
"Items.$": "$.Items"
}
- ResultPath
$.crews
[フロー]から[Query]の下の位置へ[Map]をドラッグして追加します。
Map
の[設定]-[項目配列へのパス]で$.crews.Items
を指定します。
同じくMap
の[入力]-[配列項目を変換]で以下のJSONを指定します。
{
"phoneNumber.$": "$$.Map.Item.Value.phoneNumber.S",
"message.$": "$.message",
"senderId.$": "$.senderId"
}
[アクション]から[Amazon SNS]のPublish
をMap
の中にドラッグして追加します。
SNS Publish
の[設定]で[Integration type]をAWS SDK
に変更し、[APIパラメータ]に以下のJSONを指定します。
{
"PhoneNumber.$": "$.phoneNumber",
"Message.$": "$.message",
"MessageAttributes": {
"AWS.SNS.SMS.SenderID": {
"DataType": "String",
"StringValue.$": "$.senderId"
}
}
}
その後、[次へ]をクリックします。
生成されたコードを確認したら[次へ]をクリックします。
今回生成されたコード(ステートマシン定義)は下記のようになります。
{
"Comment": "A description of my state machine",
"StartAt": "Query",
"States": {
"Query": {
"Type": "Task",
"Parameters": {
"TableName": "crews",
"IndexName": "areaId-index",
"ExpressionAttributeNames": {
"#areaId": "areaId"
},
"ExpressionAttributeValues": {
":areaId": {
"S.$": "$.areaId"
}
},
"KeyConditionExpression": "#areaId = :areaId"
},
"Resource": "arn:aws:states:::aws-sdk:dynamodb:query",
"ResultSelector": {
"Items.$": "$.Items"
},
"ResultPath": "$.crews",
"Next": "Map"
},
"Map": {
"Type": "Map",
"End": true,
"Iterator": {
"StartAt": "SNS Publish",
"States": {
"SNS Publish": {
"Type": "Task",
"Resource": "arn:aws:states:::aws-sdk:sns:publish",
"Parameters": {
"PhoneNumber.$": "$.phoneNumber",
"Message.$": "$.message",
"MessageAttributes": {
"AWS.SNS.SMS.SenderID": {
"DataType": "String",
"StringValue.$": "$.senderId"
}
}
},
"End": true
}
}
},
"ItemsPath": "$.crews.Items",
"Parameters": {
"phoneNumber.$": "$$.Map.Item.Value.phoneNumber.S",
"message.$": "$.message",
"senderId.$": "$.senderId"
}
}
}
}
[ステートマシンの作成]をクリックして作成を完了します。
ステートマシンを作成できました。不足しているDynamoDBへのアクセス権限を付与するために[IAMでロールを編集]をクリックします。
今回はAWS管理ポリシーのAmazonDynamoDBReadOnlyAccessをアタッチしました。(ポリシーは必要に応じて用意してください)
動作
Step Functionsのコンソールに戻り、入力で下記のようなJSONを指定して、ステートマシンを実行します。a001
のエリアにいるクルーにTaito-Ku
に移動するように通知する入力です。
{
"areaId": "a001",
"message": "Please move to Taito-Ku.",
"senderId": "AllocateApp"
}
実行が成功しました。
それぞれのクルーの電話番号の端末でもSMSのメッセージが受信できています。
参考
- Step Functions の入出力処理 - AWS Step Functions
- AWS Step FunctionsステートマシンからDynamoDBテーブルをQueryする | DevelopersIO
- [AWS Step Functions] Mapステートを使用して複数の宛先にSMSメッセージを送信する | DevelopersIO
以上