[新機能] Amazon API GatewayプライベートAPIとVPCエンドポイントでプライベートなサーバーレスアプリ構築
ども、大瀧です。
昨日、API Gatewayの新機能としてプライベートAPIがリリースされ、同時にAPI GatewayがVPCエンドポイントに対応しました。
API Gatewayは、AWS Lambdaとの組み合わせでAWSにおけるサーバーレスアプリケーションを実現する鉄板構成です。今回追加された2つの機能で、VPCやDirect Connectなどのプライベートなネットワークからのみアクセスできるプライベートなサーバーレスアプリを構築できるようになりました。その様子をご紹介します。
プライベートなサーバーレスアプリの構成
VPCエンドポイントは、AWSでプライベートなネットワークを提供するVPCからインターネットを経由せずにAWSサービスにアクセスできる機能です。最近対応サービスが増えてきており、今回VPCエンドポイント経由でAPI Gatewayにもアクセスできるようになりました。
一方でAPI Gatewayはこれまでインターネットからのアクセスのみを想定し、リージョンごとにエンドポイントを持つ地域タイプとエッジロケーションを利用するエッジ最適化タイプから選択していました。今回、リージョンごとにVPCエンドポイントを経由するアクセスのみ可能となるプライベートタイプが追加されたわけです。
プライベートタイプは一部 *1を除くAPI Gatewayのほとんどの機能が利用できるため、バックエンドにLambdaを構成することでVPCエンドポイント経由でプライベートネットワークにサーバーレスアプリケーションを提供できます。
作成手順
今回はAPI GatewayのサンプルAPI PetStoreをVPCからアクセスできるように、東京リージョンで構成してみます。
1. VPCエンドポイントの作成
VPCやDirect ConnectからアクセスするためのVPCエンドポイントの作成をVPC管理画面のメニュー[エンドポイント] - [エンドポイントの作成]から行います。[サービスカテゴリ]は「AWSサービス」のままにし、サービス一覧からAPI Gateway(com.amazonaws.<リージョン名>.execute-api
)を選択します。
加えてVPCサブネット(基本的には全部選択)およびセキュリティグループ(API GatewayはHTTPS:443
なのでそれを許可するルール)を選択、エンドポイントを作成します。
エンドポイント一覧には、プライベートネットワークから接続するためDNS名がいくつか表示されます。それぞれ解説します。
execute-api.<リージョン名>.amazonaws.com
: ドキュメントにあるプライベートDNS名のひとつ。任意のAPI Gatewayにアクセスできるが、証明書のCNが合わないため実用的ではない。Direct Connect経由のオンプレミスからは直接引けない点に注意。*.execute-api.<リージョン名>.amazonaws.com
: ドキュメントにあるプライベートDNS名のひとつ。後の手順で作成するAPI Gatewayのリソース名をサブドメインに指定してアクセスする。Direct Connect経由のオンプレミスからは直接引けない点に注意。vpce-XXXX-XXXX.execute-api.<リージョン名>.vpce.amazonaws.com
: ドキュメントにあるパブリックDNS名のひとつ。Hostヘッダに2のドメインを指定しないと動作しないため、あまり実用的では無い。vpce-XXXX-XXXX-<AZ名>.execute-api.<リージョン名>.vpce.amazonaws.com
: ドキュメントにあるパブリックDNS名のひとつ。3と同様あまり実用的では無い。
というわけで、特別な事情がない限り2を常用することになると思います。
APIの作成
続いてAPI GatewayでAPIを管理画面の[APIの作成]から行います。今回は[APIの例]でサンプルのPetStoreをインポートしつつ、[名前と説明]の[エンドポイントタイプ]で「プライベート」を選択します。
APIを作成したら、画面上部のパンくずリストからAPIのリソースID(PetStore(XXXXXX)
のXXXXXX
)を確認します。これがアクセスするリソースURLのサブドメインになります。
続いて画面左のメニューから[API] - [PetStore] - [リソースポリシー]を選択し、画面右下にある[ソースVPCホワイトリスト]ボタンをクリックしてリソースポリシーのテンプレートを呼び出します。
以下のJSONドキュメントがテキストエリアに貼り付けられるので、13行目の値を作成したVPCエンドポイントのIDに書き換えて[保存]をクリックします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | { "Version" : "2012-10-17" , "Statement" : [ { "Effect" : "Allow" , "Principal" : "*" , "Action" : "execute-api:Invoke" , "Resource" : [ "execute-api:/*" ], "Condition" : { "StringEquals" : { "aws:sourceVpce" : "vpce-XXXXXXXXXXXX" } } } ] } |
画面左のメニューから[API] - [PetStore] - [リソース]を選択し、[アクション]ボタンをクリックし[APIのデプロイ]を選択します。[デプロイされるステージ]は[新しいステージ]で任意のステージ名(今回はv1
)としてデプロイすればOKです。
早速VPCに配置したEC2からアクセスしてみると...
$ curl https: //XXXXXXXX .execute-api.ap-northeast-1.amazonaws.com /v1/pets/ [ { "id" : 1, "type" : "dog" , "price" : 249.99 }, { "id" : 2, "type" : "cat" , "price" : 124.99 }, { "id" : 3, "type" : "fish" , "price" : 0.99 } ]$ |
正常にレスポンスが返ってきました。ホスト名のIPアドレスを調べてみると...
$ host XXXXXXXX.execute-api.ap-northeast-1.amazonaws.com XXXXXXXX.execute-api.ap-northeast-1.amazonaws.com is an alias for execute-api.ap-northeast-1.amazonaws.com. execute-api.ap-northeast-1.amazonaws.com has address 172.31.17.157 execute-api.ap-northeast-1.amazonaws.com has address 172.31.45.78 execute-api.ap-northeast-1.amazonaws.com has address 172.31.12.159 |
CNAMEになっていて、IPアドレスはVPCエンドポイントで設定したVPCサブネットのプライベートIPが返ってきています。VPC内で通信が完結していることがわかりますね。
まとめ
API GatewayプライベートAPIとVPCエンドポイントを利用して、サーバーレスアプリをプライベートサービスとして構築する様子をご紹介しました。Internal ELBのようにサーバーレスで開発するマイクロサービスを内部同士で呼び出すケースなどに利用できそうですね。
考察
興味深いのは、VPCエンドポイント側にはAPI GatewayのAPIを特定する設定を特に持たないところです。それゆえ任意のAWSアカウントのAPIにVPCエンドポイント経由でアクセスできるので、API Gatewayのリソースポリシーできちんと制限しないといけないわけですが、逆手に取るとクロスアカウントでAPIを提供する手段としてオープンなプライベートAPIを作成することも可能だったりします。同様の機能で承認プロセスを踏むエンドポイントサービスもありますが、あちらよりも簡単に提供する手段として利用できるかもしれません。API Gatewayのカスタム認証やAPIキーを用いてアクセス元を識別する感じにすると良さそうですよね。
また、インターネットに出ない経路なので各種閉域サービスとの組み合わせも模索したいですね。VPCエンドポイントの制約でAWSハードウェアVPNは利用できないためDirect Connect経由での閉域接続サービスでの利用を検討する価値がありそうです。IoT向け閉域サービスのSORACOM Canalのピア元VPCでAPI Gateway用のVPCエンドポイントを用意しエンドポイントIDをユーザーに提示してくれると、プライベートAPI経由でサーバーレスアプリケーションを提供できて便利そうです。SORACOMさん、ご検討ください!