こんにちは、ディーネットの山田です。
API Gateway(プライベート)で、IPアドレスによるアクセスでAPI Gateway(プライベート)を利用したいとお客様よりご相談がありnginxをインストールしたEC2でリバースプロキシすることで、実現できないか構成を検討してみましたので紹介します。
今回のブログでは、nginxの設定内容を紹介します。
目次
はじめに
API Gateway(プライベート)について
API Gateway(プライベート)の仕様として、VPCエンドポイントの作成が必要となります。
VPCエンドポイントには、VPC内のIPアドレスが割り当てされますが、IPアドレスに対してそのままHTTPSアクセスをしてもAPI Gatewayを介した実行を行うことができません。
理由としては、API Gatewayのサービス側がどのAPIを実行すればよいかIPアドレスにアクセスされただけでは判断できないからです。
IPアドレスに対してそのままHTTPSアクセスしてAPI Gatewayを実行する場合は、以下いずれかの対応が必要です。
- Hostヘッダーを上書き
- x-apigw-api-idヘッダーを付与
VPC エンドポイントとプライベート REST API の関連付けまたは関連付けの解除
curlで言うところの以下のようなやり方が必要
$ curl -v -k -H 'Host: {<api-id>.execute-api.<region>.amazonaws.com}' "https://{VPCエンドポイントのIP}/{stage}/{path}"
--- or ---
$ curl -v -k -H 'x-apigw-api-id: {<api-id>}' "https://{VPCエンドポイントのIP}/{stage}/{path}"
AWSさんのドキュメントを転記させていただきます
解決策
- EC2にnginxでリバースプロキシを構築し、リバースプロキシ側でAPI Gatewayの実行に必要なヘッダを付与してリクエストすることで、上記のcurlと同じことを実現させます。
全体構成図
nginxの設定内容
-
nginxの設定は一例です。
server { listen 80 default; server_name _; root /usr/share/nginx/html; location / { resolver {VPC内にあるAWS標準のリゾルバIP} valid=5s; proxy_set_header x-apigw-api-id {API GatewayのID}; set $apiendpoint {VPCエンドポイントのDNS名}; # VPCエンドポイントから提示されるSSL証明書は無視する proxy_ssl_verify off; proxy_ssl_server_name off; proxy_request_buffering off; proxy_pass https://$apiendpoint; break; } }
要点
-
以下のような設定を記載すると、nginxが起動時にのみ名前解決を行いVPCエンドポイントのIPアドレスを固定保持してしまうため、都度名前解決を行ってくれる仕組みを導入します。
-
IPアドレスを固定保持してしまう設定
proxy_pass https://{VPCエンドポイントのDNS名};
-
定期的にVPCエンドポイントの名前解決を行いIPアドレスを取得してくれる設定
resolver {VPC内にあるAWS標準のリゾルバIP} valid=5s; set $apiendpoint {VPCエンドポイントのDNS名}; proxy_pass https://$apiendpoint;
※上記の例では、TTLに関係なく5秒経つと新しく名前解決を行ってくれます。
動作確認
- リバースプロキシサーバ上で、curlを実行してAPI Gatewayを介してLambdaから応答が返ってくることを確認しました。
$ curl "http://127.0.0.1/Prod/hoge" {"datetime": "2022-10-28 03:49:38.486590", "message": "お元気そうですね", "id": "0000", "status": "ok"}
所感
- nginxのリバースプロキシを使用して、API Gateway(プライベート)のAPIを実行させることができました。
- API Gateway(プライベート)はサーバレスなのでサーバの存在を意識する必要ありませんが、EC2を使ってしまうことでEC2のリソース管理が必要となります。
参考サイト
Amazon API Gateway でのプライベート API の作成
nginxでIPアドレスをキャッシュしないようにするために
プロフィール
テクニカルサポートは卒業して、フロントサイドでお客様環境の構築をさせていただいております。
たまに、テクニカルサポートでご対応させていただくことがあるかもしれませんが、その際はよろしくお願いいたします。
インフラ系のエンジニアですが、時々休日プログラマー(Python、PHP)をやっております。
LINK
クラウドベリージャム:プロフィールページ