サーバーレスに画像リサイズとDB構築。LambdaからS3とRDSを同時に扱うには
LambdaからS3やRDSを操作した時の備忘録です。サーバーレスにS3イベントをフックして画像処理を走らせたり、RDSのMySQLを操作するLambda Functionを作りたいと思いました。
画像アップロートのタイミングでサムネイルを生成させたり、画像検索データベースを自動構築してくれたら非常に楽ですよね。
photo by Mr. Alex Garcia - Double Cliche on flickr
構成図と結論
考えている構成図は以下のようなイメージです。結論を先に言ってしまうと、S3のPutイベントをVPCに置いたLambda functionが受けて、LambdaからRDSに接続、またS3に対してはVPCエンドポイント越しからアクセスする事にしました。
目次
VPCに置くべきか?
ここに至るまでに躓いたのが、LambdaをVPCへ置くか否かでした。VPCの外に配置したLambdaからはRDSにアクセスできなくなり、VPCに置くと今度は逆にS3へアクセスできなくなります。
各サービス | Lambda (No VPC) | Lambda on VPC |
---|---|---|
S3 | ◯ | X |
RDS | X | ◯ |
S3にアクセスできないのはLambda on VPCがインターネットにアウトバンドすることができない仕様だからです。また、RDSへセキュアにアクセスするためには、EC2からRDSにアクセスする時と同じように、VPCのサブネットからアクセスしたいところです。
従来の回避策
前述の問題を回避するために、いくつか方法が提案されていました。まず最初に、Lambda VPCがサポートされる以前ではRDSを開放(インバウンド 0.0.0.0/0)する方法が紹介されていました。
AWS LambdaでRDS(MySQL)に接続してみた | Qiita
http://qiita.com/Keisuke69/items/cba4b501e91da95188f8
さらに踏み込んで、RDSに安全にアクセスするために、SecurityGroupにLambdaのIPアドレスが追加し、LambdaからセキュアにRDSへアクセスする方法も紹介されていました。
LambdaからセキュアにRDSに接続する | ナレコムAWSレシピ
http://recipe.kc-cloud.jp/archives/7388
また、Lambda VPCからS3にアクセスする手段としてはNAT InstanceまたはNAT gatwayを介して、外部からからS3にアクセスする方法もあるようです。
VPC Lambdaからs3へアクセスする | Qiita
http://qiita.com/ijin/items/94c0bc4b8f6f5e77a591
いずれにしても、構築の手間や維持費用が多く掛かる事がわかりました。
VPC Endpoint for S3を使う
そこで今回はVPCエンドポイントを使うことにしました。VPCエンドポイントを作っておくとAWS網内でS3へのトラフィックを終端できるようになり、Lmabda VPCからS3に接続。もちろんRDSも使えるようになります。VPCエンドポイントについては以下が参考になりました。
AWSでS3を使う場合は必ずVPCエンドポイントも作成しておくクセをつけましょう。| 株式会社ビットクリア
https://www.bitclear.co.jp/vpcendpoint/
NAT Instanceとの違いも分かりやすかったです。VPCからアクセスできるのはいいですね。
S3 VPCエンドポイントを利用するメリット | Qiita
http://qiita.com/SatoHiroyuki/items/b611485b6ec736e9076f
ここで注意点としてはVPC Endpoint for S3のリージョンはVPCを扱うリージョンに制限されてしまいます(VPCに置いたLambdaが東京リージョンならばS3も東京リージョンのみとなる)。あと、aws-sdk
からS3に接続する際にはS3認証のVersion4を指定する必要があるそうです。具体的にはsignatureVersion
を指定しないとlambdaからのアクセスが拒否されタイムアウトしてしまいます。
VPC Private Network 内の Lambda Function から boto3 で S3 を操作する | Qiita
http://qiita.com/sokutou-metsu/items/47c00bb381e1b103e878#_reference-734313aae611eb61bfe7
ということで
最終的なlambda functionはざっくりと以下のようになりました。
1 | 'use strict'; |
リサイズ処理とDB処理の順番を考え中です。リサイズ処理は以下が参考になりました。
AWS Lambdaを使ってS3にアップロードされた画像をリサイズする | Qiita
http://qiita.com/awm-kaeruko/items/00d92cf2484405fb5579
Lambdaのコンソール画面ではnode.js 4.3より古いBlue printが削除されてしまった事情から、従来あったimage-processing-service
が参照できなくなっています。あとQiitaのサンプルをそのまま記述すると無限ループになるので要注意です(^^;)一度タイムアウトまで無限リサイズさせてしまいましたw
最後に
VPC Endpointを活用することで、LambdaからS3やRDSを操作することができるようになりました。roleでアクセスを絞り込んでいけば、安全なものが構築できるかなぁと思っていますが、いかがでしょうか。