はじめに
こんにちは。アプリケーションサービス部の保田(ほだ)です。
最近二度寝にハマっています。安心して二度寝するために一度目は5時ぐらいに起きるのがポイントです。
そんな訳で今回はプライベート API に何とかしてカスタムドメインを割り当てる方法を考えます。
背景
VPC エンドポイント経由で API Gateway を実行したい場合、プライベート API を利用することになります。
また、 API Gateway にはカスタムドメインを割り当てることができます。 ただし、プライベート API にはカスタムドメインを割り当てることはできません。
カスタムドメイン名はプライベート API ではサポートされていません。
マネジメントコンソール上で設定すると特にエラーも出ずに設定できてしまうのですが、実際に使おうとするとダメです。
ただし、以下の方法を使えば無理やり実現することができます。
おことわり
私の書く記事の恒例となりつつありますが、 ドキュメントには書いてないので、ご利用は自己責任でお願いします 。
構成
ザックリとした構成図はこのようになります。ALB は(可用性のために)少なくとも二つのサブネットに紐づける必要がありますが、負荷分散は今回の話題と直接関係がないため省いています。
EC2 インスタンスにいる人が API Gateway に到達したい様子を示していると考えて見て下さい。
前提
以下は事前に用意されているものとします。
- プライベート API (何かしらのステージにデプロイ済み)
- API Gateway 用の VPC エンドポイント
また、話を分かりやすくするために API Gateway の背後には Lambda 関数がいて、そいつは "Hello, World!"
を返すように実装されているとします。
やり方の概略
設定手順の概略は以下のような感じです。
- ACM 証明書を発行
- API Gateway の VPC エンドポイントの IP アドレスをターゲットとしてターゲットグループを作成
- 内部 ALB を作成
- カスタムドメインで ALB を引けるように Route53 のプライベートホストゾーンを作成してエイリアス A レコードを設定
- API Gateway のコンソール上でカスタムドメインを作成し、対象のプライベート API を指すようにマッピングを設定
- VPC内からカスタムドメイン(実際は ALB へのエイリアスレコード)に対してアクセス
(カスタムドメイン名を割り当てている)ALB の向き先を VPC エンドポイントの IP アドレスにしてやることで、「カスタムドメイン → ALB → VPC エンドポイント → プライベート API」という経路を確保している感じになります。
詳しく
API Gateway 以外に用意しないといけないものがいくつかあります。
適当な最終形を仮定して、順番に説明いたします。
欲しいもの
以下のようなカスタムドメインを作りたいとします。
test.hoda-example.com
要するに cURL コマンドを使えば次のようになって欲しい、とします。
$ curl https://test.hoda-example.com "Hello, World!"
1. ACM 証明書を発行
まず、カスタムドメインを保護する証明書が必要なので、用意します。パブリック証明書で大丈夫です。
今回の場合で言えば、ドメイン名を *.hoda-example.com
として発行すればよいでしょう。
2. ALB のターゲットグループを作成
API Gateway の VPC エンドポイントの IP アドレスをターゲットとして、ターゲットグループを作成します。
この IP アドレスは、 VPC エンドポイントを紐づけたサブネット毎に割り当てられ、コンソール上では対象のエンドポイントの [サブネット] タブから確認することが出来ます。
ターゲットとするプロトコルは HTTPS 、ポートは 443 です。
3. 内部 ALB を作成
内部 ALB を作成します。
リスナーに割り当てる証明書は先ほど作成した ACM 証明書を指定します。 ターゲットは先ほど作成したターゲットグループを指定します。
もちろん VPC エンドポイントのある VPC 内に作成します。
4. プライベートホストゾーンにレコードセットを登録
Route53 にてプライベートホストゾーンを作成します。
今回の場合で言えば、ドメイン名 hoda-example.com
のプライベートホストゾーンを作成します。
紐づける VPC は VPC エンドポイントのある VPC です。
作成したら、目的のカスタムドメイン名から先ほど作成した ALB を引いてこれるようにエイリアス A レコードを設定します。
今回の目標に照らして言えば、次のようなレコードを登録することになります。
レコード名 | タイプ | ルーティングポリシー | 値/トラフィックのルーティング先 |
---|---|---|---|
test.hoda-example.com |
A | シンプル | dualstack.xxxxxx.ap-northeast-1.elb.amazonaws.com. (※) |
※ コンソール上でポチポチ選んでいけばサジェストされる値です。
5. API Gateway 側のコンソールでカスタムドメインを作成
先ほどまでの手順で、一応目標のカスタムドメインに対してアクセスすればプライベート API を実行することができます。
が、この状態だとどの API を実行するかの情報がどこにもないため、x-apigw-api-id ヘッダーもしくは Host ヘッダーが必要です。
$ curl https://test.hoda-example.com/dev -H 'x-apigw-api-id: xxxxx' $ curl https://test.hoda-example.com/dev -H 'Host: xxxxx.execute-api.ap-northeast-1.amazonaws.com'
なので、カスタムドメイン名をどの API に対応させるかを設定します。
API Gateway のコンソール上で、左ペインから [カスタムドメイン名] を選択し、 [作成] ボタンを押下します。
ドメイン名は test.hoda-example.com
を入力します。
エンドポイント設定の選択肢として [リージョン] と [エッジ最適化(REST API のみサポート)] とあり、ドキュメントの通り「プライベート」が選べないのですが、上記のどちらを選択肢ても大丈夫です。
証明書は *.hoda-example.com
を選択します。
カスタムドメインを作成したら、 [ドメイン名] の一覧に今しがた作成したドメイン名が表示されるようになりますので、それを選択し [API マッピング] のタブから [API マッピングの設定] を選択します。
ここで「どの API」、「どのステージ」、「どのパス(オプション)」を設定できますので、目的のプライベート API を選択します。 ステージやパスの設定はよしなに…。
6. カスタムドメインにアクセス
おもむろに VPC 内のリソースから cURL コマンド等でカスタムドメインに対してアクセスします。
$ curl https://test.hoda-example.com "Hello, World!"
欲しい状態が作れましたね。
補足
こちらで紹介した方法ですが、いくつか微妙なバリエーションがあります。
パブリックから接続する
まずはパブリックから接続するパターンです(なぜそんなことをする必要があるかはさておき…)。 先に記載した概略との主な相違点は以下の通りです。
- 外部 ALB を作成
- パブリックホストゾーンにエイリアスレコードを作成
これでインターネット経由で一度 ALB から VPC に入ったあと VPC エンドポイント経由で API Gateway に到達できます。
何故か分からないですが、すごく遅いです。なので微妙です。
パブリックホストゾーンを使う
次にプライベートホストゾーンではなく、パブリックホストゾーンにエイリアスレコードを作るパターンです。
- 内部 ALB を作成
- パブリックホストゾーンにエイリアスレコードを作成
これでも VPC 内からであれば API Gateway まで到達可能です。 パブリックから接続しようとした場合の挙動としては、「IP アドレスは分かるけど、それがプライベート IP だからその先に到達できない」という感じです。
なのでこれも微妙そうですね。
さいごに
肌感覚で「閉域網でサーバーレス」というケースが増えている実感があり、序盤の技術検証として話題に上ることがあるので書いてみました。
下準備が多いですが、そこまで仕様のウラを突いた特殊な技、という訳でもない気がするので、その内普通に使えるようにならないかな~~~と思う次第です。