つい最近GPSロガー的なのを作りましたが、毎回毎回SFTPで接続するなどしてログを取り出すのも面倒なのでDynamoDBに蓄積するようにします。
単純な蓄積だけでも良かったのですが、それではあまり面白くないので、セッションID的なのを生成するAPIも一緒に作っています。
「クライアントで勝手に生成すればよくね?」という感じですが、AWSのサービス間連携における練習も兼ねているのでなるべくサーバサイドで完結するようにします。
今はやりのサーバレス!
使ったサービス
LambdaはセッションIDの生成に使っています。データの蓄積はAPI GatewayからDynamoDBに直で行います。
ちなみに後述しますが、一番はまったのはIAMの設定です。
準備
DynamoDB
今回は次の2テーブルを利用します。
- データを蓄積するテーブル
- セッションIDの一覧を蓄積するテーブル
データ蓄積はセッションIDをパーティションキーに、時間を入れるカラムをソートキーにしています。
セッションID一覧はセッションIDのパーティションキーのみ。全て文字列です。
IAM
IAMでロールの設定もします。
ポリシーはこんな感じです。
PutItemをデータ蓄積用のテーブルとセッションID保管用のテーブルに割り当てておきます。後で気づいたけど多分Scanはいらない。
もう1つ、ロールの信頼関係を編集して、API GatewayとLambda(のプリンシパル?)を信頼しておきます。デフォルトだとEC2(ec2.amazonaws.com)が信頼されているはず。
実は設定した時はこの辺があまりよく分かっておらず、2〜3時間ぐらいはまりました。こうしておかないとAPI GatewayとLambdaでアクセスする時に怒られましたね。
APIをテストした時に失敗していて、ログに「Execution failed due to configuration error: API Gateway does not have permission to assume the provided role」というエラーが返ってきた場合はこの辺を見直してみましょう。
Lambda
Lambdaの役割はセッションIDを生成して、DynamoDBに保管し、そのIDを返すという動きだけです。
l
の数字を書き換えれば文字数を変える事ができます。
API Gateway
下準備は整ったので、API Gatewayも設定してしまいます。
作成するAPIは次の2つです。(カッコ内はメソッド)
- /post(POST)
- /start(GET)
/startでセッションIDを取得して、/postに投稿します。
/start
セットアップ時に統合タイプをLambda 関数にして、リージョンと関数名を適切に設定すれば終わりです。関数動かすだけなのでこんなもんです。
/post
こっちは少々大変です。
初期設定は次のような感じです。
この場合、このリクエストではPutItemを実行したいのでアクションにはPutItemを設定します。
問題はHTTPメソッドでですが、APIドキュメントのSample RequestがPOSTで送っているようなのでPOSTにしてみたら成功しました。
お次はリクエスト本文と挿入パラメータを照らし合わせる必要がありますので、その辺を設定します。
作成したメソッドの統合リクエストを開いて、一番下の本文マッピングテンプレートから、次のような流れで設定します。
- リクエスト本文のパススルーをなしに
- JSONでリクエストを受ける前提なので、Content-Typeをapplication/jsonで追加
- テンプレートを入力するフィールドが現れるので、先ほどのAPIドキュメントを参考にテンプレートを構築
テンプレートは、今回は下記に設定しています。
$input.path('$.hogehoge')
の$.
から下に送信したリクエストのJSONが含まれるため、それを利用して値を取得します。
今回は最小限なのでこんな感じですが、他にも色々設定できます。
APIテスト時は上記パラメータが含まれるJSONを構築して、それでテストします。
問題なくデータが蓄積されていれば、デプロイして終わりです。
クライアント側
クライアント側はシェルスクリプトで処理しています。
gpsdを利用しているので、gpspipeの-w
を使うことでJSONの出力が取れます。
そこから緯度経度と時間を抽出し、それにセッションIDを合わせてリクエストを飛ばします。
本当は毎秒飛ばしたいくらいなのですが、とりあえず10秒おきに送信するようにしています。
あとは一通り試してみて、どんどんDynamoDBに蓄積されていれば終わりです。
まとめ
ちなみに
200リクエストちょい送っていますが、今月は1円しかかかってません。やっす。
(Lambda/DynamoDB/Data Transferは毎月の無料枠内で収まっていて、API Gatewayの利用料しかかかってない)
参考
- APIGateWay+Lambda+DynamoDB - Qiita
- AWS API Gatewayを使ってDynamoDBにデータを読み書きしてみた - Qiita
- API Gatewayから、AWS Lambdaを使わずにDynamoDBにアクセスする - Taste of Tech Topics
- Execution failed due to configuration error: API Gateway does not have permission to assume the provided role | A different story…
- https://forums.aws.amazon.com/thread.jspa?threadID=220021