Amazon Web Services ブログ
リバースプロキシを使ってAmazon API Gatewayのプライベートエンドポイントにカスタムドメイン名を実装する
この投稿は、プリンシパル・ソリューション・アーキテクトのHeeki Park氏、シニア・アプリケーション・アーキテクトのSachin Doshi氏、シニア・ソリューション・アーキテクトのJason Enderle氏 の投稿を翻訳したものです。
Amazon API Gateway は、開発者が Virtual Private Cloud (VPC) 内からのみアクセス可能なプライベート REST API を作成することが可能です。プライベート API へのトラフィックはセキュアな接続を介して送信され、AWS ネットワーク内、特にお客様が管理している VPC 内に留まり、パブリックインターネットから保護されます。このアプローチは、送信されたトラフィックの機密性を確保することで、お客様の規制要件やセキュリティ要件に対応するために使用できます。このため、プライベート API Gateway エンドポイントは、マイクロサービスやデータ API で使用されるような内部 API の公開に適しています。
マイクロサービス・アーキテクチャでは、チームはしばしば個別の AWS アカウントでコンポーネントを構築・管理し、企業固有のカスタムドメイン名を使用してこれらのプライベート API エンドポイントにアクセスすることを好みます。カスタムドメイン名は、ホスト名と API へのパスのエイリアスとして機能します。これにより、クライアントは覚えやすい URL を使用して接続しやすくなり、また基礎となる API エンドポイントの URL が変更された場合でも同じ URL を維持できます。カスタムドメイン名は、企業内の機能に従って API の構成を改善することもできます。例えば、標準的な API Gateway の URL フォーマット: “https://api-id.execute-api.region.amazonaws.com/stage” を “https://api.private.example.com/myservice”に変換できます。
概要
このブログポストは、プライベートエンドポイントのフロントエンド呼び出しとバックエンド統合パターンに関するドキュメントと、以前に公開された以下で紹介する2つのブログに基づいています。
最初のブログでは、VPC 対応の Lambda 関数と mTLS を使用したコンテナベースのアプリケーションを使用して、API Gateway からプライベート API エンドポイントを利用する方法を説明しています。2つ目のブログは、 AWS Fargate や Amazon EC2 を使用してデプロイされた マイクロサービス API へのプライベートバックエンドインテグレーションの実装を解説するものです。このブログではこれらを拡張し、NGINX リバースプロキシを使ってプライベートエンドポイントにカスタムドメイン名を実装することで、API エンドポイントへのアクセスを簡素化できるようにします。
このソリューションでは NGINX を使用します。NGINX は高性能な仲介役として機能し、プライベートネットワーク内のトラフィックを効率的に転送することができます。構成マッピングファイルは、カスタムドメインとAWSアカウント間の対応するプライベートエンドポイントを関連付けます。この設定マッピングファイルはコードとして管理され、下流の環境と本番環境への統制されたデプロイに使用することができます。
次の図は、コンポーネント間の相互作用と API リクエストのパスを示しています。このユースケースでは、共有サービスアカウント(アカウントA)がカスタムドメイ ンのマッピングを一元管理し、プロバイダーアカウント(アカウントBとアカウントC)のプライベート API エンドポイントへの AWS PrivateLink 接続を作成する役割を担っています。
- API へのリクエストは、VPC または VPC にルーティング可能な別のデバイス内から、プライベートカスタムドメインを使用して行われます。例えば、リクエストはドメイン https://api.private.example.com を利用するかもしれません。
- Amazon Route 53 の プライベートホストゾーンのエイリアスレコードは、プライベートの Elastic Load Balancing (ELB) の FQDN に解決します。ELB は、ネットワークロードバランサー (NLB)またはアプリケーションロードバランサー (ALB) のいずれかに構成することができます。
- ELB は AWS Certificate Manager (ACM) 証明書を使用して、対応するカスタムプライベートドメインのTLS (Transport Layer Security) を終了します。
- ELB リスナーはリクエストを関連する ELB ターゲットグループにリダイレクトし、そのターゲットグループはリクエストを AWS Fargate 上で動作する Amazon Elastic Container Service タスクに転送します。
- Fargate サービスは、NGINX ベースのコンテナをホストし、1つ以上のプロバイダーアカウントのプライベート API エンドポイントへのリバースプロキシとして動作します。Fargate サービスは、CPU 使用率を自動的に追跡するメトリックを使用してスケールするように構成されています。
- Fargate タスクは、PrivateLink VPC エンドポイントを介して、プロバイダアカウント B またはアカウント C の適切なプライベートエンドポイントにトラフィックを転送します。
- API Gateway のリソースポリシーは、API を要求するために使用される特定の VPC エンドポイント、HTTP メソッド、およびソースドメインに基づいて、プライベートエンドポイントへのアクセスを制限します。
このソリューションでは、認証ヘッダ、Content-type ヘッダ、カスタムヘッダなど、上流の呼び出しのヘッダで見つかった追加情報を、プロバイダアカウント(アカウント B およびアカウント C)のプライベートエンドポイントに変更せずに渡します。
前提条件
カスタムドメイン名を使用するには、TLS 証明書と DNS エイリアスの2つのコンポーネントが必要です。この例では、TLS 証明書の管理に ACM を使用し、DNS エイリアスの作成に Route 53 を使用しています。
ACM は、TLS 証明書を統合するためのさまざまなオプションを提供しています:
- 既存の TLS 証明書を ACM にインポートします。
- ACM で電子メールベースの検証を使用して TLS 証明書を要求します。
- DNS ベースの検証を使用して ACM に TLS 証明書を要求します。
- プライベート CA を使用して ACM に TLS 証明書を要求します。
次の図は、各オプションに関連する利点と欠点を示しています。
このソリューションでは、DNS ベースの検証 (オプション3) を使用して ACM に TLS 証明書を 要求します。ルートドメイン(example.comなど)が登録された パブリックホストゾーン が、 ターゲットアカウントに既にデプロイされているものと仮定します。その後、このソリューションは ACM を使用して、デプロイ時に設定マッピングファイルに指定されたドメイン名の所有権を検証します。
デプロイされたパブリックホストゾーンでは、DNS 検証を使用してプライベートの子ドメイン(api.private.example.comなど)をデプロイできるため、ソリューションのデプロイ時に証明書の検証を自動化するIaC(Infrastructure as Code)デプロイが可能になります。さらに、DNS ベースの検証では、ACM 証明書の有効期限が切れる前に自動的に更新されます。
このソリューションでは、特定の VPC エンドポイント、すなわち共有サービスアカウント(アカウント A)内の execute-api、logs、ecr.dkr、ecr.api、Amazon S3 ゲートウェイが必要です。execute-api の VPC エンドポイントでプライベート DNS を有効にすることはオプションであり、ソリューションの要件ではありません。これにより、VPC 内のアプリケーションは NGINX リバースプロキシを通じてプライベート API エンドポイントに到達できますが、パブリック API ゲートウェイのエンドポイントも解決できます。
サンプルのデプロイ
このパターンを自分のアカウントにデプロイするには、サンプルのAWS Cloud Development Kit (CDK) または GitHub で利用可能な Terraform コードを使うことができます。
このソリューションでは、YAML ベースの設定マッピングファイルを使用して、カスタムドメインとプライベート API エンドポイント間のマッピングを追加、更新、または削除します。デプロイ中に、自動化されたInfrastructure as Code(IaC)スクリプトは提供された YAML ファイルを解析し、以下を実行します:
- NGINX 設定ファイルを作成します。
- NGINX 設定ファイルを標準 NGINX コンテナイメージに適用します。
- マッピングファイルを解析し、アカウント A に必要な Route 53 プライベートホストゾーンを作成します。
- アカウント A にワイルドカードベースの SSL 証明書(*.example.comなど)を作成します。ACM は、それぞれのパブリックホストゾーン(example.comなど)を使用してこれらの証明書を検証し、ELB リスナーにアタッチします。デフォルトでは、ELB リスナーは最大25の SSL 証明書をサポートします。ワイルドカードは、無制限の数のサブドメインを保護するために使用され、複数のサブドメインの管理と拡張を容易にします。
マッピングファイルのフィールドの説明
Property | Required | Example Values | Description |
---|---|---|---|
CUSTOM_DOMAIN_URL | TRUE | api.private.example.com | プライベート API に必要なカスタム URL |
PRIVATE_API_URL | TRUE | https://a1b2c3d4e5.execute-api.us-east-1.amazonaws.com/dev/path1/path2 | 対象となるプライベート・エンドポイントの実行 URL |
VERBS | FALSE | [“GET”,” POST”, “PUT”, “PATCH”, “DELETE”, “HEAD”, “OPTIONS”] | このプロパティは、API Gateway リソースポリシーを作成するために使用されます。1つまたは複数のメソッドをカンマ区切りのリストとして指定できます。このプロパティを指定しない場合は、すべての動詞が許可されます。 |
プライベートエンドポイントに API Gateway リソースポリシーを使用する
自分の VPC または別のアカウントの VPC からプライベートエンドポイントへのアクセスを許可するには、リソースポリシーを実装する必要があります。リソースポリシーは、VPC エンドポイント、API パス、API メソッドなどの特定の条件に基づいてアクセスを制限するために使用できます。この機能を有効にするには、以下の手順に従います:
- IaC(Infrastructure as Code)の導入を完了します。
- プロバイダーアカウント(アカウント B やアカウント C など)に API Gateway リソースポリシーを作成または更新します。このポリシーには、共有サービスアカウント(アカウント A)の VPC エンドポイント ID を含めます。
- API をデプロイして、プロバイダーアカウント(アカウント B やアカウント C など)に変更を適用します。
API Gateway のリソースポリシーをコードで更新するには、GitHub リポジトリのドキュメントとコード例を参照してください。
マッピングファイルのアップデートのデプロイ
カスタムドメインとプライベートエンドポイント間のマッピングを追加、更新、または削除するには、マッピングファイルを更新してから、以前と同じ手順でデプロイを再実行します。
既存の Infrastructure as Code パイプラインを使用してマッピングファイルの更新をデプロイすることで、人的ミスのリスクを低減し、トレーサビリティを追加し、構成のドリフトを防止し、デプロイプロセスを既存の DevOps プロセスとガバナンスプロセスに従わせることができます。
例えば、設定マッピングファイルを別のソース管理リポジトリに保存し、各変更をそのリポジトリにコミットすることができます。各変更がデプロイメントプロセスのトリガーとなり、デプロイメントプロセスは設定変更をチェックし、適切なデプロイメントを実施します。必要であれば、変更管理プロセスが確実に実施されるように、手動チェックまたはチケットプロセスのいずれかを強制するゲートを導入できます。
ソリューションのコストを理解する
このソリューションで言及されているサービスのほとんどは、リクエストの数によって決定される使用量に応じて課金されます。
ただし、時間単位または月単位の費用が発生するサービスもいくつかあります。これには、Route 53 ホストゾーンの月額料金、VPC エンドポイントの時間課金、Elastic Load Balancing、Fargate で NGINX リバースプロキシを実行する時間課金などがあります。特定のワークロードに基づいてこれらのオプションのコストを見積もるには、AWS Pricing Calculator を利用することができます。ここでは、このソリューションで実装されたアーキテクチャに関連するおおよそのコストの例を示します。
結論
このブログポストでは、カスタムドメイン名のリバースプロキシを使って、AWS アカウント間や VPC ネットワーク内で API Gateway を安全にプライベートエンドポイントを利用できるソリューションを紹介しました。このソリューションは、API Gateway とカスタムドメイン名を持つプライベートエンドポイント間のマッピングを管理する簡素化されたアプローチを提供し、シームレスな接続性とセキュリティを確保します。
サーバーレスの学習リソースについては、Serverless Land をご覧ください。
この投稿は、Heeki Park氏、Sachin Doshi氏、Jason Enderle氏 によって書かれた Implementing custom domain names for Amazon API Gateway private endpoints using a reverse proxy の日本語訳です。この記事はソリューションアーキテクトの松本侑也が翻訳しました。