背景
「AWSを使ってAPIを構築したい」という要望は山程あると思います。
その場合、API GatewayとLambdaを用いてサーバレスに構築することがほとんどです。
しかし、Lambdaにはメモリ・実行時間の制限があったり、Lambdaベースでコーディングしなければならなかったりといった不自由な点も存在します。
もしかしたらこれらの条件が理由でLambdaではなくEC2上にサーバを構築したいということがあるかもしれません。AWSに不慣れな場合、この方が手っ取り早い場合もあります。
そこで、今回はAPI Gatewayを通してEC2内に立てた任意のポートにリクエストを送る手順をご紹介します。
設計
API Gateway+EC2といいましたが、間にLambdaを噛ませています。
LambdaからこのEC2サーバにHTTP経由でリクエストを送信します。
通常、Lambdaはネットワーク接続不可能に設定されていますが、private subnet内に設置することによって同VPC内へのアクセスを実現しています。
前提
- public subnet内に設置されたEC2サーバはすでに構築済みであること
- まずはLambdaを張るためのprivate subnetが作成されていること(VPCのCIDRがa.b.0.0/14ならsubnetのCIDRをa.b.16.0/20とか)
Lambda
まずEC2にリクエストを送信するためのLambda関数を構築します。
関数の作成
関数を作成します。今回はNode.jsを選択しました(好きにやってください)。
関数は以下のように記述しています(好きにやってください)。
この場合、環境変数のURLにEC2のエンドポイントURLを設定してください。
var request = require('request-promise');
exports.handler = function(event, context) {
console.log(process.env["URL"])
var options = {
uri: process.env["URL"],
headers: {
"Content-Type": "application/json",
"Authorization": process.env["BASIC_TOKEN"]
},
body: JSON.stringify(event),
method: 'POST'
}
return new Promise((resolve, reject) => {
request(options)
.then((res) => {
resolve(res);
})
.catch((err) => {
resolve(err);
});
});
}
IAM Roleの付与
LambdaからVPCエンドポイントに接続するには以下のIAMポリシーが必要になります。
- DescribeNetworkInterface
- CreateNetworkInterface
- DeleteNetworkInterface
よって、LambdaのIAM Roleにこれを付与します。僕はEC2EnrollAccess
というポリシーを作成し、LambdaのIAM Roleにアタッチしました。
VPCの設定
関数のVPCの設定からカスタムVPCを選択します。以下のように設定します。
VPC: EC2に使用されているもの
サブネット: 作成したprivate subnet(2つつけろって言われてるけど1つでもいけます)
セキュリティグループ: なんでもいいです(僕はEC2と同じルールをアタッチしています)
以前の項でIAM Roleを付与し忘れているとエラーになるので注意してください。
EC2のセキュリティルールの設定
EC2のセキュリティグループから、EC2で構築している任意のポート(僕の場合は80)を設定します。IPアドレスにLambdaのあるprivate subnetのCIDRブロックを設定してください。
セキュアにするため、他のソースからのアクセスは許可しないでください。
テスト
この時点でLambdaからテストしてみてください。LambdaからEC2への接続が確認できると思います。
API Gateway
次にAPI GatewayからLambdaにリクエストを送信するREST APIを構築します。以下を参考にAPIキーの設定まで行なってください。
統合リクエストに作成したLambda関数を設定することによって、API Gatewayのエンドポイントにリクエストを送信すればEC2のサーバにAPIを叩き、レスポンスが返ってきます。
最後に
これでAPI Gateway以外のエンドポイントからアクセスしようとしてもEC2までにはたどり着けず、かつAPI Gatewayの認証によって鍵を持っていないとアクセスできないセキュアなREST APIが設計できました。
もしこのAPIを使用する時間が限られているならば、EC2を極限までサーバレスにするために起動・停止もLambdaでコントロールしてあげましょう。