目的
セキュリティが厳しい企業だと、インターネットを通してS3等のAWSのサービスを利用する事が難しい事があります。このケースでは通常はVPC Endpointを利用するのですが、一部のAWSのサービスにはVPC Endpointが用意されていません。この記事では、この問題に対応するために、API GatewayのAWSサービスとの連携機能を利用する方法を紹介します。
システム構成
以下のような、クライアントがS3からファイルを取得するシステムを構築します。S3は、VPC Endpointが用意されていますが、試験が容易なのでこちらを利用します。
作成手順
VPC Endpointの作成
以下の条件でAPI GatewayについてのVPC Endpointを作成する。
【サービス名】com.amazonaws.ap-northeast-1.execute-api
【VPCおよびサブネット】API Gatewayを配置したいVPCおよびサブネットを選択
【プライベートDNS名】有効
【セキュリティグループ】API GatewayからHTTPSのインバウンド/アウトバウンドが許可のもの(必要に応じて作成する)。
IAM Roleの作成
以下の手順でIAM Roleを作成する。
作成したロールのARNを控えておく
- IAMのメニューから、「ロールを作成」を選択。
- API Gatewayのユースケースを選択し、ポリシー等は変えずにロールを作成する。
- 作成したロールを選択し、「AmazonS3ReadOnlyAccess」ポリシーをアタッチする。
この作成の仕方だと「信頼されたエンティティ」にAPI Gateway(apigateway.amazonaws.com)が追加される
ロールの作成時には、ポリシーの追加が出来ないので、この手順にする
S3バケットの作成
S3バケットを作成し、テスト用のデータを登録しておく(以下では、index.htmlを登録したものとする)。
API Gatewayの作成(参考)
-
API Gatewayの「APIの作成」でREST API(プライベート)を以下の条件で構築する。
-
作成したREST APIを選択してリソースを追加する。パスがすべてマッピングされるように、「プロキシとリソースを設定する」にチェックすると、自動でリソース名およびリソースパスが設定される(パスの最後が+なら、パス階層すべてに対応される)。
-
ANYを選択し、以下のようにメソッドを登録する(パス階層(+)の場合には、メソッドの初期登録画面でAWSサービスが選択出来ない。このため、適当なメソッドを登録する。保存出来ればなんでも良い)。
-
「統合リクエスト」リンクを選択し、以下のようにメソッドを変更する(test-document-2853はバケット名)。
-
以下の内容で「リソースポリシー」を設定する
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": "execute-api:Invoke", "Resource": "execute-api:/*", "Condition" : { "StringNotEquals": { "aws:SourceVpc": "{VPCエンドポイントのID}" } } } ] }
-
「メソッドレスポンス」を編集する。
200のレスポンスを追加し、レスポンスヘッダに以下を追加する。- Timestamp
- Content-Type
- Content-Length
-
「統合レスポンス」のヘッダーのマッピングを編集する。
- Timestamp: integration.response.header.Date
- Content-Type: integration.response.header.Content-Type
- Content-Length: integration.response.header.Content-Length
-
アクセスをテストする。
- メソッド(/{proxy+}-ANY)を選択し、「テスト」リンクをクリック。
- メソッドにGETを、パスにindex.html(S3バケットに登録されているファイル)を設定し、「テスト」を押下。
-
ステージにデプロイを行う。
API Gatewayはステージにデプロイしない限り設定が有効にならない
テスト
- VPCに対してVPNを接続する等して、VPCにアクセス出来る端末を準備する。
- API Gatewayのステージから、アクセスURL取得する。
- ブラウザで、2で取得したURLに「/index.html」を付与しアクセスを確認する。
まとめ
手順はかなり面倒ですが、VPC Endpointが存在しないAWSサービスに対してプライベートアクセスが出来そうです。次は、Cognitoに対して同様の設定を行なって、インターネットアクセス無しでCognito連携が可能かを試してみます。