本記事では、Regional APIエンドポイントタイプで定義されたパブリックAPIを扱うAPI Gatewayについて解説します。
TL;DR — 実装手順はこちら
クラウド中心の現代のアーキテクチャにおいて、APIはサービス間通信を支える基盤です。Amazon Web Services(AWS)が提供する強力なAPI Gatewayを使えば、開発者はあらゆる規模でAPIの作成・公開・運用・保護を行えます。
よくあるシナリオとして、VPC内のサービスからパブリックAPIとプライベートAPIの両方にアクセスする必要があるケースが挙げられます。パブリックAPIのURLには次の2つの形式があります。
1. API Gatewayが自動生成するデフォルトURL: api-id.execute-api.REGION.amazonaws.com
2. カスタムドメイン名(例: api.mydomain.com)。任意のドメイン名と証明書を利用できます。
まずカスタムドメイン名における課題と解決方法を説明し、その後、API Gatewayが生成したURLを利用する方法について解説します。
問題となるのは、カスタムドメイン名をRoute 53以外でホスティングし、CNAMEレコードを使用しているケースです。
本記事の目的は、VPC内からプライベートAPIとパブリックAPIへシームレスにアクセスできる環境を構築し、効率的かつセキュアなサービス間通信を実現することにあります。
パブリックなカスタムドメイン名をRoute 53でホストし、API Gatewayドメイン名へAliasレコードで向けている場合、同一VPC内からパブリックAPIとプライベートAPIを併用しても問題は起こりません。
しかし以下で見ていくように、外部DNSプロバイダー(CNAMEレコードしか使えない)を利用する場合は、正しいDNS解決とSSL証明書の検証を成立させるために追加の手順が必要になります。
用語
API Gatewayドメイン名
API Gatewayドメイン名とは、APIのカスタムドメイン名を構成した際にAWSが作成する、AWSマネージドのエンドポイントです。APIのデフォルトエンドポイントapiID.execute-api.REGION.amazonaws.comに対するエイリアスとして機能し、TLS終端と扱いやすいURLを実現します。
仕組みは次のとおりです。
1. パブリックAPIエンドポイントの2タイプにおけるAPI Gatewayドメイン名の構造
- Edge-Optimized:
グローバルで低レイテンシーのアクセスを実現するため、CloudFrontディストリビューション(例: d123.cloudfront.net)を使用します。
- Regional:
リージョン固有のエンドポイント(例: d-abc123.execute-api.us-east-1.amazonaws.com)を使用します。
2. DNS構成
- DNSプロバイダー(例: GoDaddy):
カスタムドメイン名(api.mydomain.com)をAPI Gatewayドメイン名(例: d-abc123.execute-api.us-east-1.amazonaws.com)へ向けるCNAMEレコードを作成します。
- GoDaddyでのDNSレコード例:
Name: api.mydomain.com
Type: CNAME
Value: d-abc123.execute-api.us-east-1.amazonaws.com
- このレコードにより、
api.mydomain.com宛てのトラフィックがAPI Gatewayのエンドポイントへルーティングされます。
3. 証明書の関連付け
- AWS Certificate Manager(ACM)証明書:
API Gatewayでカスタムドメイン名を定義する際、ACM証明書(例: *.mydomain.com)を紐付けます。
- 証明書のSubject Alternative Name(SAN)には、カスタムドメイン名(例:
api.mydomain.com、またはトップレベルのワイルドカード*.mydomain.com)が含まれている必要があります。 - API Gatewayはこの証明書をエッジレイヤーでのTLS終端に使用します。
4. 全体の連携 — リクエストの流れ
- クライアントがhttps://api.mydomain.comへリクエストを送信します。
- DNSがAPI Gatewayドメイン名(例:
d-abc123.execute-api.us-east-1.amazonaws.com)に解決します。 - AWSのDNSがAPI GatewayドメイN名をAWS GatewayサービスのパブリックIPに解決し、ACM証明書によるTLS終端とトラフィックの負荷分散が行われます。
- API Gatewayが、カスタムドメイン名にマッピングされたAPIとステージを呼び出します。
問題点
問題の核心は、プライベートAPIへのアクセスに必要なAPI Gateway用VPCエンドポイントにあります。VPCエンドポイントでPrivate DNSを有効化していると、パブリックAPIへアクセスする際に厄介な問題が発生し得ます。具体的には、SSL証明書の問題でパブリックAPI呼び出しが失敗してしまうのです。これを理解するには、このアーキテクチャ構成下でのDNS解決の挙動を押さえる必要があります(Appendix A参照)。
カスタムドメイン名を持たないパブリックAPIには、インターネット上の誰もがアクセスできるパブリックエンドポイントURLしか存在しません。
パブリックAPIはインターネット経由でのみ呼び出せるため、Private DNSが有効化されたAPI Gateway用VPCエンドポイントを持つVPC内からこのURLを呼び出そうとすると、インターネットではなくVPC経由でAPIを呼び出そうとし、HTTP 403(Forbidden)エラーが返されます。
パブリックAPIをカスタムドメイン名にマッピングする場合は、証明書が必要です。
Route 53でAlias型Aレコードを作成し、カスタムドメイン名でパブリックAPIを呼び出すように構成すれば、Private DNSが有効なAPI Gateway用VPCエンドポイントが存在する場合でも、VPCからプライベートAPIとパブリックAPIの両方を呼び出せます。
ドメインを外部プロバイダーでホストしている場合は、外部DNSにCNAMEレコードを作成することになります。
このCNAMEレコードこそが問題の根本原因です。
カスタムドメイン名でパブリックAPIを呼び出すと、それをAPI Gatewayドメイン名にマッピングするレコードを取得するためのDNSルックアップが発生します。続いて、最初のルックアップで返されたAPI Gatewayドメイン名のIPアドレスを取得するため、2回目のDNSルックアップが必要になります。
Private DNSが有効でなければ、ルックアップはパブリックAPIのパブリックIPを返します。これが本来期待される動作です。
このパブリックIPはAWS Gatewayサービスのものであり、同サービスはカスタムドメイン名に関連付けられた証明書のSubject Alternative Name(SAN)からカスタムドメイン名を探します。カスタムドメイン名の証明書(例: mydomain.com)はAPI Gatewayドメイン名と関連付けられているため、SSLハンドシェイクは成功し、パブリックAPIが呼び出されます。
一方、VPCにPrivate DNSが有効化されたAPI Gateway用VPCエンドポイントがある場合、このPrivate DNSがAPI Gatewayドメイン名のルックアップをキャッチし(execute-api.REGION.amazonaws.comのすべてのサブドメインを捕捉するため)、VPCエンドポイントのElastic Network Interface(ENI)に割り当てられたプライベートIPを返します。
このプライベートIPはAPI Gatewayサービスのアドレスであり、apiID.execute-api.REGION.amazonaws.com形式のプライベートAPIエンドポイントURLに該当する内部URLエンドポイントしか受け付けません。
結果として次のような状態になります。

Private DNSが有効なAPI Gateway用VPCエンドポイントが存在する状態でパブリックAPIを呼び出した結果
このように、VPC内からパブリックAPIを呼び出そうとすると必ずSSLハンドシェイクが失敗し、接続がブロックされてしまいます。
ソリューションの概要
すでに説明したとおり、API Gateway用VPCエンドポイントでPrivate DNSが有効になっていると、execute-api.REGION.amazonaws.comに対するDNSルックアップがすべてプライベートIPに解決されてしまい、カスタムドメイン名を使ったパブリックAPI呼び出しがSSL検証で失敗します。解決策は、Route 53のプライベートホストゾーンを利用してDNSの優先順位付けを行うこと、いわゆるSplit-Horizon / Split-View DNSです。
プライベートホストゾーン(PHZ)を用意すると、VPC内からのDNSルックアップは、他のパブリックDNSサーバーを参照する前にPHZを先に確認するようになります。
たとえば、トップレベルドメインmydomain.comをホストしているGoDaddy DNSサーバーがあるとします。
api.mydomain.comをパブリックAPIにマッピングする場合は、このサブドメインをPHZ DNSにホストしてsplit-view DNSを構築します。
これにより、VPC内から発行されたapi.mydomain.comのルックアップはPHZから応答され、API Gatewayを使わない他のサブドメイン(VPCエンドポイントが捕捉しない別サービスを指すものなど)へのアクセスはパブリックDNSで解決されるようになります。
このソリューションは、次の3つの要素で構成されます。
- VPCエンドポイント: プライベートAPIへのアクセス用(Private DNS有効)
- プライベートホストゾーン: split-view DNSの構築用
- PHZ内のAlias型Aレコード: パブリックAPI Gatewayドメイン名へトラフィックを誘導するためのレコード
実装手順
前提条件
- Route 53以外でホストされ、インターネットから呼び出し可能なカスタムドメイン名を持つパブリックAPI Gateway。または、Route 53でホストされているもののAlias型AレコードではなくCNAMEレコードでカスタムドメイン名を向けているパブリックAPI。
- パブリックAPIを呼び出したいVPC内に定義された、Private DNSが有効なAPI Gateway用VPCエンドポイント。
このVPCエンドポイントが既にある場合は、下記のステップ2から始めてください。
無い場合は、プライベートAPIを呼び出すことができません。
1. プライベートAPIにアクセスするためのAPI Gateway用VPCエンドポイントを構成する
このエンドポイントが既にある場合は、ステップ「2」へお進みください。
- AWSコンソールでVPCコンソール > エンドポイントへ移動します。
com.amazonaws.REGION.execute-apiのインターフェースエンドポイントを作成します。- Private DNSを有効化します(デフォルト設定)。
- VPCからのインバウンドHTTPS(ポート443)を許可するセキュリティグループを割り当てます(またはプライベートAPI Gateway APIの呼び出しを許可したいVPC内の特定リソースのIPからのみ許可するセキュリティグループでも構いません)。
2. プライベートホストゾーンを作成する
- Route 53コンソールで、パブリックなカスタムドメイン名のAPIパス(例:
api.mydomain.com)に一致するPHZを作成します。
パブリックドメインに、呼び出したいがAPI GatewayにマッピングされていないURLが存在する場合(例: dev.mydomain.comがAPI Gatewayではなくロードバランサーを指している場合)、プライベートホストゾーンのドメイン名にはAPIの完全なカスタムドメイン名(例: api.mydomain.com)を指定してください。
ドメイン内のすべてのサブドメインがAPI Gateway APIにマッピングされている場合は、トップレベルのmydomain.comをドメイン名に使用します。
- ゾーンをVPCに関連付けます。

カスタムドメイン名用のPHZを作成し、このドメインへのアクセスが必要なVPCに関連付けます
3. DNSレコードを設定する
- APIで使用される各ドメインに対して、Alias型Aレコードを作成する必要があります。
たとえばapi.mydomain.comとspecial-api.mydomain.comがある場合、それぞれにレコードを作成します(api用とspecial-api用)。レコードタイプには「A」を選択してください。
- レコード名について:
- カスタムドメイン名がAPIの完全なドメイン名と同じ場合は、「レコード名」にサブドメイン(「api」)を入力せず、空欄のままにしてください。たとえばAPI Gatewayで使う唯一のサブドメインとしてapi.mydomain.com用のPHZを作成した場合、レコード名フィールドは空欄のままにします。
- 複数のサブドメインをAPI Gatewayにマッピングしているためトップレベルのmydomain.comを使用している場合は、各レコードの「レコード名」にAPIの名前を入力します。たとえば一方には「api」、もう一方には「special-api」と入力します。
- 「alias」ボックスにチェックを入れてAliasレコードに設定します
- 「Alias to API Gateway API」を選択します
- APIのリージョンを選択します
- パブリックAPIのリージョナルエンドポイント(カスタムドメイン名用に作成されたAPI Gatewayドメイン名)を選択します。
名前は次のような形式です。
d-abc123.execute-api.REGION.amazonaws.com
- 一覧に表示されない場合は、API Gatewayコンソールの「カスタムドメイン名」→ API Gatewayドメイン名からコピーしてください。
- レコードを保存します

新しく作成したプライベートホストゾーンがVPCで利用可能になるまで、Route 53で多少時間がかかる場合があります。
本ソリューションのアーキテクチャはAppendix Bを参照してください。
動作確認
パブリックAPIを呼び出すために、インターネット接続のあるEC2をVPC内で稼働させる必要があります。
EC2インスタンスに接続し、以下のURLをご自身のものに置き換えて実行します。
curl -v https://your-public-api.yourdomain.com/your-path
次のような出力が得られるはずです。

PHZの作成・構成前は、Private DNS(API Gateway用VPCエンドポイントに関連付けられたもの)がカスタムドメイン名に対してプライベートIP(10.0.3.79)を返しており、このプライベートIPはVPCエンドポイントのENIのものでした。カスタムドメイン名用のPHZを作成すると、API GatewayドメイN名のパブリックIPが取得できるようになり、本例では次のとおりです。
IPv4: 44.221.197.141, 34.192.177.183, 34.232.190.93
デフォルトのパブリックAPI Gateway URLを使う場合
プライベートAPIとパブリックAPIを併用するには、まずAPI Gateway用VPCエンドポイントに関連付けられたPrivate DNSを無効化します。次にexecute-api.REGION.amazonaws.comという名前のPHZを作成し、プライベートAPIをホストするVPCへのアクセスを許可したいすべてのVPCに関連付けます(別リージョンのVPCに関連付けるケースは、本記事「ボーナス」セクションに関連します)。
続いて、すべてのAPI Gateway API-IDを捕捉するためのワイルドカードレコードを以下のように作成します。

このリージョンのプライベートAPI用ホストゾーンを作成
次に、VPCエンドポイントのDNSを指す「キャッチオール」レコードを以下のように作成します。

このリージョンのすべてのプライベートAPI用キャッチオールレコードを作成
これにより、us-east-1で定義されたプライベートAPI GatewayのすべてのURLがこのPHZに捕捉され、API Gateway用VPCエンドポイントのプライベートIPアドレスが返されるようになります。
カスタムドメイン名を持つパブリックAPIについては、そのカスタムドメイン名用のPHZを作成すれば問題が解決することは前述のとおりです。
カスタムドメイン名を持たないパブリックAPIについては、APIのAPI IDを使ったAliasレコードを追加し、それをパブリックURLへ向ける必要があります。
たとえば、us-east-1にURLがbmf11pk5je.execute-api.us-east-1.amazonaws.comのパブリックAPIがあるとします。
これをVPC内から呼び出すと、前述のカスタムドメイン名のシナリオと同じく「Forbidden(403)」が返されます。これを解決するには、「bmf11pk5je」というレコードを追加し、次のように呼び出しURLへ向けます。

これで、このレコードに定義したパブリックAPIをVPC内から呼び出せるようになります。同じリージョンで別のパブリックAPIを呼び出したい場合も、同様にAliasレコードを追加していきます。
ボーナス
あるリージョンに配置したプライベートAPIを、別のAWSリージョンのVPCから呼び出す方法を解説します。
問題点
プライベートAPIは、同一リージョン内の複数VPC間であれば容易に共有できます。各VPCにAPI Gateway用VPCエンドポイントを配置し、これらのVPCからのアクセスを許可するリソースポリシーをプライベートAPIに設定したうえで、API設定からVPCエンドポイントをプライベートAPIに追加するだけです。
ところが、VPCがプライベートAPIをホストするリージョンと異なるリージョンにある場合は、これでは機能しません。
その場合は、以下の手順が必要です。
- 2つのVPC、すなわちプライベートAPIをホストするVPCとアクセスを付与したいVPCをピアリングします。
VPCピアリングを行うには、両VPCのCIDRブロックが重複していないことを確認する必要があります。 2. プライベートAPIをホストするAPI Gatewayリージョン用のプライベートホストゾーンが無ければ、新規に作成します。 3. プライベートホストゾーン(PHZ)の名前は次のとおりにします。
execute-api.REGION.amazonaws.com
4. このPHZを、当該リージョンのAPI Gateway用VPCエンドポイントと、アクセスを付与したいVPCの両方に関連付けます。
5. PHZにAlias型Aレコードを追加します(「alias」ボックスにチェックを入れてaliasに設定)。続いてドロップダウンから「Alias to VPC Endpoint」を選択します。
6. アクセスを付与したいVPCのリージョンを選択します。
7. このVPC内のAPI Gateway用VPCエンドポイントを選択します。
8. ピアVPCのCIDRブロックを、VPCエンドポイントのセキュリティグループに追加します。これがないとピアVPCからの通信がブロックされます。
9. レコードを保存します。
以上が完了すれば、別リージョンのVPCからプライベートAPIを呼び出せるようになります。
VPCピアリングを利用しているため、プライベートAPI Gatewayのリソースポリシーでピア接続元VPCからのトラフィックを承認する必要はなく、デプロイ先のメインVPCからの承認だけで十分です。これは、ピアVPCから発信されたトラフィックであっても、API Gatewayへの通信は同一VPC内のVPCエンドポイント経由で届くためです。
ただし、このクロスリージョンピアリング構成でも、プライベートAPIと同じVPCに定義されたパブリックAPIへアクセスしようとすると、SSL証明書エラーという同じ問題が発生します。別リージョンであっても、execute-api.REGION(APIがデプロイされているREGION)用のPHZと関連付けられているため、パブリックAPI用のPHZを定義しない限り、VPCエンドポイントのプライベートIPを呼び出そうとしてしまうのです。
クロスリージョンか否かに関わらず、プライベートAPIとパブリックAPIの両方を呼び出したい場合は、本記事前半の手順に従ってください。
Appendix A
下図は、Private DNSが有効なAPI Gateway用VPCエンドポイントを持つVPC内のEC2インスタンスから、パブリックAPI Gatewayを呼び出した際の挙動を示しています。

PHZが無いVPCからパブリックAPIを呼び出した場合
- EC2が
https://api.mydomain.com,を呼び出そうとし、DNSルックアップが行われる - DNSからの応答はAPI Gatewayドメイン名
- 2回目のDNSルックアップが行われ、API Gateway用VPCエンドポイントに関連付けられたPrivate DNSが捕捉する
- VPCエンドポイントのプライベートIPアドレスが返される
- EC2はこのプライベートIPアドレス経由でAPIを呼び出そうとする
- プライベートIP経由で到達するAPI Gatewayサービスは
*.execute-api.REGION.amazonaws.comに対する証明書を提示するが、api.mydomain.comには対応していないため、証明書エラーが返される
Appendix B
下図も同様に、Private DNSが有効なAPI Gateway用VPCエンドポイントを持つVPC内のEC2インスタンスからパブリックAPI Gatewayを呼び出した際の挙動を示しています。ただし今回は、カスタムドメイン名用のプライベートホストゾーンも定義されているケースです。

PHZがあるVPCからパブリックAPIを呼び出した場合
インターネットからパブリックAPIを呼び出す
- APIのカスタムドメイン名(例:
api.mydomain.com)について、外部のドメインホスティングサービス(例: GoDaddy)にDNSルックアップが行われる - クエリは、このカスタムドメイン名に対するAPI Gatewayドメイン名を返す
- API Gatewayドメイン名がAWSのRoute 53に問い合わせられる
- パブリックAPI GatewayサービスのパブリックIPアドレスが返される
- このパブリックIPでAPI Gatewayサービスが呼び出され、
api.mydomain.comの証明書と関連付けられているためSSLが終端され、API Gatewayの該当ステージのターゲットが呼び出される
VPC内からプライベートAPIを呼び出す
6. プライベートAPIはapiID.execute-api.REGION.amazonaws.com形式のURLを持ちます。このURLが、Private DNSが有効なAPI Gateway用VPCエンドポイントを持つVPCから呼び出されると、リクエストはこのPrivate DNSによって処理されます。
7. Private DNSは、API Gateway用VPCエンドポイントのENIのプライベートIPを返します。
8. このプライベートIP経由で到達するAPI Gatewayサービスは*.execute-api.REGION.amazonaws.com用の証明書を持っているため、このURLを使ったプライベートAPI呼び出しは認証を通過し、プライベートAPIのターゲットへ転送されます。
VPC内からパブリックAPI Gateway APIを呼び出す
9. カスタムドメイン名用に作成されたプライベートホストゾーンDNSが、自身のドメイン名配下のクエリを捕捉して処理します。
10. PHZにはAlias型Aレコードがあり、カスタムドメイン名に関連付けられたAPI Gatewayドメイン名のパブリックIPを返します。
11. このパブリックIPがインターネットゲートウェイ経由で呼び出され、API Gatewayサービスのアドレスに到達します。パブリックIPで到達するサービスはカスタムドメイン名とAPIドメイン名の証明書関連付けを保持しているため、SSLハンドシェイクは成功してTLSが終端されます。リクエストはAPI GatewayパブリックAPIの該当ステージのターゲットへ転送されます。
お問い合わせ
本記事が皆さまの参考になりましたら幸いです。さらに詳しく知りたい方や、当社サービスにご関心のある方は、ぜひお気軽にご連絡ください。お問い合わせはこちらから。
参考文献
もっともシンプルな解決策は、パブリックなカスタムドメイン名をRoute 53でホストし、Alias型Aレコードを使うことです。これなら、Private DNSが有効なAPI Gateway用VPCエンドポイントが存在する状況でも、パブリックAPIとプライベートAPIを呼び出せます。
それが難しい場合は、本記事で紹介した方法を活用してください。
留意点
- Private DNSが有効なAPI Gateway用VPCエンドポイントが存在する場合、当該リージョン内のすべてのAPI GatewayパブリックAPIへの呼び出しが証明書不一致エラーで失敗します。本記事で
api.mydomain.comのみを取り上げたのはあくまで例示にすぎません。たとえばapi.mydomain.com、api.example.com、myapi.myspecialdomain.comがある場合、各ドメインに関連性がないため、それぞれにPHZを用意する必要があります。 - 本記事ではREST APIを前提に説明していますが、これはプロトコルの問題ではなくネットワークとDNSに関する問題のため、HTTP API(検証済み)やWebSocket API(未検証)でも同様に機能します。