始めに
AWSの鉄板構成の一つにAmazon S3ウェブサイトホスティング機能を使用してEC2などのサーバーを立てずに静的ウェブサイトを構築する方法があります。
通常はS3の前段にCDNサービスであるCloudFrontを設置して
コンテンツキャッシュを効かせる
サイトのSSL化
を実現する形が王道です。
今回、とある案件で「静的なサイト」だけど、外部公開はしないものをささっと作りたい
というお題目を頂き、S3+ALBの構成で構築する方法で対応しました。
構成イメージ
社内NWとはTransitGatewayでつながり、内部ALBとVPCエンドポイントを介してS3の静的HTMLにアクセスする構成になります。
構成における重要ポイント
今回構築した構成はAWS公式に紹介されている構成になりますので詳細手順については以下を参照頂くとよいと思います。
https://aws.amazon.com/jp/blogs/news/internal-static-web-hosting/
本記事では細かな手順というより、構築するうえでのポイントをお伝えしたいと思います。
S3 VPCエンドポイント経由でALBとつなぐ
ALBのターゲットとしてS3は直接選択できないですが、S3 VPCエンドポイント(インタフェース型)を用意することでIPアドレス指定としてターゲット指定可能となります。
S3 VPCエンドポイントにアタッチするセキュリティグループは以下のようにしておきます。
ルール | プロトコル | ソース | 備考 |
インバウンド | HTTP/HTTPS | ALBのSG | |
アウトバウンド | ALL | 0.0.0.0/0 | デフォルト |
S3 VPCエンドポイントを作成後、作成したS3 VPCエンドポイントの詳細画面を開き、
「サブネット」タブにあるIPアドレスを控えておきます。
これをALBのターゲットとして指定することになります。
S3バケットはアクセスURLとしたいFQDNの名称とする
静的HTMLを置くS3バケットのバケット名はWebアクセスする際のURLドメインに指定したいFQDNの名称とします。
また、タイトルに記載はしていますが、実際にはS3バケット作成時に静的ウェブサイトホスティングを有効にする必要はありません。バケットへのリクエストはS3 VPCエンドポイントからプライベートREST APIを経由してなされるためです。
S3バケットのバケットポリシーではS3 VPCエンドポイントからの操作を許可する
前述の通り、S3 VPCエンドポイントを介してS3上のコンテンツにアクセスするため、
S3 VPCエンドポイントからの操作を許可しておきます。
{
"Version": "2012-10-17",
"Id": "Policy1415115909152",
"Statement": [
{
"Sid": "Access-to-specific-VPCE-only",
"Principal": "*",
"Action": "s3:GetObject",
"Effect": "Allow",
"Resource": ["arn:aws:s3:::yourbucketname",
"arn:aws:s3:::yourbucketname/*"],
"Condition": {
"StringEquals": {
"aws:SourceVpce": "vpce-1a2b3c4d"
}
}
}
]
}
内部ALBを用意する
今回の要件は外部公開しないということがあるため、ALBは内部(internal)として用意します。
ターゲットタイプは事前に控えておいたS3 VPCエンドポイントのIPアドレスにします。
ここで、ヘルスチェックについて1つ気をつけておくポイントがあります。
通常はHTTPステータスとして「200 OK」とすることが一般的ですが、S3に対してリクエストする今回の構成の場合、200以外のコードも返ってくるため、「307 GET」、「405 HEAD」の2つもステータスに追加しておきます。
リスナー及びルールの設定
今回のS3 VPCエンドポイントはREST APIエンドポイントになるため、index.htmlを省略する意味での末尾「/」でのアクセスを行うと、XMLディレクトリリストが返ってきてしまいます。
これを回避するために、リダイレクトルールで末尾「/」のときは「/index.html」にリダイレクトするように設定します。
内部ALBをアクセスしたいFQDNで引けるようDNS登録する
最後に内部ALBのエンドポイントを実際にアクセスしたいURLドメインのFQDNで登録します。
これはS3バケット名につけたドメインと同じ名称を指定することになります。
完全に内部に閉じるならRoute53 プライベートホストゾーンに設定となりますが、
外部からは引いた先の内部ALBには到達できないので、DNS自体は外部であっても問題ないなら通常のパブリック ホストゾーンでも構いません。
まとめ
静的なコンテンツを内部向けだけに用意したいというときにはこの構成をひとつの選択肢にしてみると素早く構築でき、且つ、インフラ運用面も楽になると思います。
ただし、王道パターンと違い、CloudFrontが前段にはいないので、大量のアクセスが予想される場合はS3リクエストのコストが高くなったり、リクエストレートにかかる可能性がある点には注意が必要です。
今回の構成を試して改めて組み合わせによっていろんな実現方法があるのだなと勉強になりました。
Comments