LoginSignup
0
1

More than 3 years have passed since last update.

CloudFront経由でDynamoDBのデータを更新する

Last updated at Posted at 2020-11-11

別サイト

に書いていたのだけどサ終してしまったので移行した記事その4
2019/03/09のもの

サーバレスでDynamoDBにデータを入れる

EC2インスタンスを立てたら負けってどこかに書いてあったのでなしでどうにかやってみる

DynamoDBにテーブルを作成

なんでもいいのでIDとアドレスを入れるやつを適当に作る
テーブル名はregisterにする

LambdaからDynamoDBを操作するIAMを作成

Lambdaで使うためのIAMを作る
名前は
lambda-dynamodb-execution-role
とでもして権限を付与。

Lambdaを作成

テーブルに対して検索と投入をするLambdaを作成
ブランクで作成し、Node.js 8.10を選択
名前は適当にregisterInsertFuncとregisterSelectFuncとでもする
実行ロールは先程作成したやつを設定

## insert
var aws = require('aws-sdk');
var dynamo = new aws.DynamoDB.DocumentClient({region: 'ap-northeast-1'});

exports.handler = (event, context, callback) => {
    console.log("event:", event);
    dynamo.put({
        "TableName": "register",
        "Item": {
            "event_id": event.event_id,
            "address": event.address
        }
    }, function( err, data ) {
        console.log("dynamo_err:", err);
        context.done(null, data);
    });
};
## select
var aws = require('aws-sdk');
var dynamo = new aws.DynamoDB.DocumentClient({region: 'ap-northeast-1'});

exports.handler = function (event, context) {

    var params = {
        TableName : 'register',
        KeyConditionExpression: "event_id = :event_id and address = :address",
        ExpressionAttributeValues: {
            ":event_id": event.event_id,
            ":address": event.address
        }
    };

    dynamo.query(params, function(err, data) {
        console.log("dynamo_data:", data);
        console.log("dynamo_err:", err);
        context.done(null, data);
    });
};

テスト用のパラメータは下記

{
  "event_id": "101",
  "address": "hogehuga@hoge.jp"
}

API Gatewayの作成

Lambdaを呼び出すためのAPI Gatewayを作成する
/eventリソースを作成してメソッドの作成でGET,POSTを作成する(PUTもあるが気にしない)

  • メソッドリクエストにパラメータ
  • 統合リクエストにマッピングテンプレート
  • メソッドレスポンスのコンテンツタイプをapplication/json;charset=UTF-8 をそれぞれ設定

{
    "event_id": "$input.params('event_id')",
    "address": "$input.params('address')"
}

/eventリソースに対してアクションからCORSの有効化をする

ここまで作業できたらAPIのデプロイを行って反映

一旦確認

ここまできたらAPI GatewayのURLが生成されるのでcurl等で確認ができる

$ curl -X GET https://[API GatewayのURL]\?event_id\=102\&address\=hogehoge
{"Items":[],"Count":0,"ScannedCount":0}
$ curl -X POST https://[API GatewayのURL]\?event_id\=102\&address\=hogehogehoge
{}

S3にコンテンツ配置

S3からAPI Gatewayを呼び出すためにhtmlを置く
event-registerというバケットを適当につくってトップにindex.htmlを配置
API Gatewayからライブラリをダウンロードして配置ってのもあったけどjQueryだけでいけたのでそっちにしてみた
PUTメソッドはなんかうまく動かなかったので諦め。。。(PUTメソッドがあったのはそのため)

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>API test</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<input type="text" id="addId" value="102" />
<input type="text" id="addAddress" value="hogehogehoge" />
<button id="add">追加</button>
<br>
<input type="text" id="searchId" value="102" />
<input type="text" id="searchAddress" value="hogehogehoge" />
<button id="search">検索</button>

<script type="text/javascript">
$('#add').click(function(){
  var addId = $('#addId').val()
  var addAddress = $('#addAddress').val()
  $.ajax({
        url: "https://[API GatewayのURL]?event_id=" + addId + "&address=" + addAddress,
        type: 'POST',
        crossDomain: true,
        dataType: 'json',
        contentType: "application/json",
        success: function (data) {
            console.info(data);
        }
    });
});
$('#search').click(function(){
  var searchId = $('#searchId').val()
  var searchAddress = $('#searchAddress').val()
  $.ajax({
        url: "https://[API GatewayのURL]?event_id=" + searchId + "&address=" + searchAddress,
        type: 'GET',
        crossDomain: true,
        dataType: 'json',
        contentType: "application/json",
        success: function (data) {
            console.info(data);
        }
    });
});
</script>
</body>
</html>

こんな感じの画面が出てボタンを押してエラーがでなければOK
c032f3500c9b956b9c859e1f803d943f.jpg

CloudFront経由でS3へアクセス

CreateDistributionでS3のevent-registerを指定

  • Restrict Bucket AccessをYes
  • Origin Access IdentityをCreate a New Identity
  • Grant Read Permissions on BucketをYes

に設定して作成
S3のバケットポリシーが更新されているのを確認してアクセスコントロールからEveryOneの権限をoffにする
これでCloudFront経由からのみS3にアクセスできるようになった
https://[CloudFrontで作成したURL]/index.html
で先程と同じ画面が出れば成功

感想

実際書いてみるとそんなに作業はないけど結構ハマった。。。
特にPUTメソッドのときだけSameオリジンポリシー制約にハマって結局わからなかった。。。
これが作成できると何ができるのって考えると
例えば事前登録サイトとかぐらいならhtmlさえちゃんと作ればだいたい作れそうだなーと思った
そうなるとインスタンス立ててサーバエンジニアが色々やることもなくてハッピーかな

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1