Amazon Lightsailのオブジェクトストレージ+CDN構成で気になる点をチェックしてみた

Amazon Lightsailのオブジェクトストレージ+CDNの構成について、オブジェクトストレージへの通信方法、オブジェクトストレージのアクセス権限まわり、そしてインデックスドキュメントの扱いについて調べてみました。
2021.10.31

はじめに

清水です。今年の夏、Amazon Lightsailでオブジェクトストレージが利用できるようになりました。これまでインスタンスなどに対して利用できていたLightsailのCDNについてもこのLightsailオブジェクトストレージに対応し、S3+CloudFrontのような環境がサクッと構築可能です。

とは言っても、個人的にはS3+CloudFrontの構成、非常に奥が深いものだと思っております。例えばオリジンとなるS3への通信やS3のアクセス許可をどう扱うか、また「/index.html」などインデックスドキュメントを補完できるかどうか、など。実際にどのようにするのかは配信環境の要件によるかと思います。オリジンへのHTTP通信が許可されるか、ランディングページのような単純な1枚のhtmlの配信で済むのか、リダイレクトなど含み複雑にhtmlが入り乱れているのか、htmlではなく画像や動画などのコンテンツの配信なのか、といった点ですね。方針の決め方としては、以下ブログエントリが参考になるかと思います。

さて、Lightsailでオブジェクトストレージが利用できるようになり、CDN連携もできるということで、上記のような細かな点、CloudFront相当のCDNからS3相当のオブジェクトストレージへの通信方法やアクセス権限がどうなっているのか、インデックスドキュメントの補完などはできるか、といった点が気になりました。実は私、これまでLightsailを実際にさわったことがなかったのですが、今回はじめてLightsailをさわりつつ、オブジェクトストレージとCDNの詳細に迫ってみたいと思います。

オブジェクトストレージの作成

まずはオブジェクトストレージを作成するため、マネジメントコンソールのLightsailのページに進みます。Lightsailのマスコットがお出迎えしてくれました。ただし、このまま[Let's get started]で進んだ場合、今回の趣旨と異なるインスタンスの起動画面になってしまいます。いったんインスタンスの起動画面はキャンセルして、画面上部の[Storage]から進み、[Create bucket]でバケットを作成します。

バケット作成画面では、ロケーション(リージョン)とストレージプラン、バケット名を決めていきます。バケット名につてはデフォルトで「bucket-[6文字のランダムな文字列]」が設定されているようです。ここではさらに「lightsail-bucket-[6文字のランダムな文字列]」としてみました。[Create bucket]ボタンでバケットを作成します。

バケット作成後の画面です。続いてこの画面の[Create distribution]ボタンからCDNディストリビューションを作成していきます。が、その前に1つ気になっていた点を確認してみました。このLightsailのバケット、Domainなどでも確認できるように実態はS3バケットかと思います。ということは通常のAWSマネジメントコンソールのS3の画面からバケットが確認できる?のかと思いましたが、実際に確認してみたところ、作成したS3バケットと思しきリソースは見つかりません。Lightsailを使用ている場合当たり前なのかもしれませんが、LightsailのリソースはあくまでLightsail側のコンソールで管理、通常のAWSサービスの画面には出てこないようですね。

CDNディストリビューションの作成

オブジェクトストレージのバケットが作成できたので、続いてこれに紐付けるCDNディストリビューションを作成していきます。先ほどのバケットの画面の[Create distribution]ボタンから進みました。ディストリビューションはグローバルリソースであること(ここはCloudFrontそのままですね)を確認しつつ、オリジンについて確認します。先ほどバケットの画面から進んだこともあり、オブジェクトストレージのバケットが選択されている状態です。(なお、オリジンが選択されていない状態ですと、Caching behaviorなどの選択項目が現れるようですが、バケットを選択している状態だとこちらの選択はないようですね。)ディストリビューションのプランとディストリビューションの名称を決め、[Create distribution]ボタンで作成です。

ディストリビューションが作成できました。ドメイン名などはCloudFrontそのままですね。また作成直後のStatusは「In progress」ということで、こちらもCloudFront同様かと思います。

なお、オブジェクトストレージのときと同様、AWSマネジメントコンソールのCloudFrontのページを確認しても、ここで作成したディストリビューションは一覧に表示されません。あくまでLightsail側のコンソールで管理となります。

Lightsailコンソールの日本語化

さて、ここまでLightsailのコンソール、英語のまま操作をしてきましたが、ディストリビューション作成後いろいろと確認している中で、日本語化できることに気が付きました。コンソール右下、言語選択画面がありますね。(Good evening!に夢中で(?)気が付きませんでした。)

日本語も選択可能です。ということで、以降は日本語化したコンソールで進めていきたいと思います。

CDNからオブジェクトストレージへの通信について

それではいよいよ、本題のLightsailのオブジェクトストレージ+CDNの構成における、細かな設定項目などを確認していきたいと思います。まずはCDNからオブジェクトストレージへの通信部分です。

S3+CloudFrontの構成であれば、(1) S3への通信をHTTPSとするのか、HTTPとするのか、という検討が可能です。またあわせて(2) S3へのアクセスについて、CloudFrontのOAI (Origin Access Identity)を使用してCloudFront以外のアクセスをブロックするのか、パブリックアクセスは一律許可するのか、という設計も必要です。

Lightsailのオブジェクトストレージ+CDN構成についてはどうでしょうか。まずはCDNからオブジェクトストレージへの通信の部分にいて確認してみます。こちらはディストリビューションの詳細画面にHTTP通信であることが明記されていました。

Lightsailドキュメントについても確認してみます。HTTPとHTTPSが選択可能ですが、オリジンがLightsailバケットの場合はHTTPのみであることが記載されていました。(ただしこの記載、現時点では英語版ドキュメントにのみ記載があります。日本語版ドキュメントについては反映がまだのようですね。)

Creating Amazon Lightsail distributions | Lightsail Documentation

ということで、現時点ではCDNからオブジェクトストレージへの通信はHTTP固定ということでした。続いて、オブジェクトストレージのアクセス権限まわりについて確認してみます。Lightsailのコンソール、ストレージからバケットを選択してアクセス権限の詳細を参照してみますが、プライベート/個々のオブジェクトを公開/すべてのオブジェクトを公開、の3種類が基本のようです。その他にもリソースアクセスやアクセスキーなどありますが、現時点ではCDNディストリビューションとは連携できないようで、個々のオブジェクトもしくはすべてのオブジェクトをオブジェクトストレージ(Lightsailバケット)側で公開する必要があるようです。今回はすべてのオブジェクトを公開(パブリックで読み取り専用)としておきました。

なお、ドキュメントを確認してみると、例えばWordPressをホスティングしているLightsailインスタンスをオリジンとし、WordPress側のプラグインでLightsailバケット内の個々のオブジェクトのアクセス権限をコントロールする、というような使い方などができるようです。

インデックスドキュメントの扱いについて

続いてはインデックスドキュメントの扱いについてです。「https://www.example.com」にアクセスすると「https://www.example.com/index.html」を表示してくれるアレですね。さらには「https://www.example.com/path」に対して、「path」がディレクトリであれば「https://www.example.com/path/index.html」を返してくれればベストです。

S3+CloudFrontの構成でこれを行おうとした場合、S3の静的Webサイトホスティングを利用することが多いかと思います。しかしS3の静的Webサイトホスティングを利用する場合、オリジンとなるS3への通信はHTTPに限定されHTTPSが利用できなくなります。またS3のアクセス権限もCloudFrontからのアクセスに限定せず、パブリックに公開することになります。これらS3の静的Webサイトホスティングの制限が許容できない場合、CloudFront側でLambda@Edgeや、最近ならCloudFront Functionsを使ってパスを補完する、という対応が必要になります。(できた!S3 オリジンへの直接アクセス制限と、インデックスドキュメント機能を共存させる方法 | DevelopersIO

さて、それではLightsailのオブジェクトストレージ+CDNの構成ではどうなっているでしょうか。オブジェクトストレージ(Lightsailバケット)に「index.html」というファイルと「path/index.html」というフォルダ+ファイルをアップロードして確認してみます。

以下、curlコマンドによるアクセス結果ですが、デフォルトでは「index.html」の補完機能はないようです。設定項目やドキュメントを確認してもこちらは見つからず、現時点でインデックスドキュメントの補完はLightsailでは実現できないようでした。

% curl -i https://dwbsxxxxxxxxx.cloudfront.net/
HTTP/2 403
content-type: application/xml
x-amz-bucket-region: ap-northeast-1
date: Sun, 31 Oct 2021 14:25:57 GMT
server: AmazonS3
x-cache: Error from cloudfront
via: 1.1 d8e9b6af48fa5d844b0f68fc85959592.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT12-C5
x-amz-cf-id: omA7slw9O8NYWkJFflsA5EFMlyg6mFW2pHr7pyWDQRUT29QsgDa0iw==

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>M24KHJYMKG9N7DF9</RequestId><HostId>bAWVXdeViVVnUcrvUa9xECiyP8glb24leIRQrSuSe1mbQBKaKBTTBMCYXIWpY7bsAf+NYtHxejs=</HostId></Error>%
% curl -i https://dwbsxxxxxxxxx.cloudfront.net/index.html
HTTP/2 200
content-type: text/html
content-length: 11
date: Sun, 31 Oct 2021 14:26:03 GMT
last-modified: Sun, 31 Oct 2021 11:11:47 GMT
etag: "49610d0b8cab2afecd6ef0c03fc1f4dd-1"
x-amz-server-side-encryption: AES256
accept-ranges: bytes
server: AmazonS3
x-cache: Miss from cloudfront
via: 1.1 d1e4d8ebe5533d5332b1c564eaf9661c.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT12-C5
x-amz-cf-id: 1kOl361Qh6F2Jkek-LpjSbdZLWd9gXsWYv8VlFU42Jm10ZhhKdzbJQ==

index.html
% curl -i https://dwbsxxxxxxxxx.cloudfront.net/path
HTTP/2 403
content-type: application/xml
date: Sun, 31 Oct 2021 14:26:04 GMT
server: AmazonS3
x-cache: Error from cloudfront
via: 1.1 16a35f2b2822aee977100c01186bf17c.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT12-C5
x-amz-cf-id: rLrVNY7F7d3E8encYe-b7r8Zls1yV_U-lNopvll0zEdoypLyD4x9Dg==

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>6Q453BNGKXD8T5HX</RequestId><HostId>ExH7OkeYkRYnE6xczNoSG6tFCE57VYGNNneMjSCRtjpfbCQGg7MxPa3vAghMwAbuNuZ4RYwtBp8=</HostId></Error>%
% curl -i https://dwbsxxxxxxxxx.cloudfront.net/path/
HTTP/2 403
content-type: application/xml
date: Sun, 31 Oct 2021 14:26:06 GMT
server: AmazonS3
x-cache: Error from cloudfront
via: 1.1 79d771190d1d4a25574af501a083c90a.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT12-C5
x-amz-cf-id: KrjWvuSmhuQjrHpcsUJ2PkEZjq2xvtngmw5SUscYtjxOrttjXb2SCA==

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>CE7FKJG72EKKG2BC</RequestId><HostId>bl5SUnnUbgPhi+rmdNypTW/wVcKnKObq1OEvI592p/3x7jHy2wjtzqB/JDCKBOwkyu1MpEqCfaE=</HostId></Error>%
% curl -i https://dwbsxxxxxxxxx.cloudfront.net/path/index.html
HTTP/2 200
content-type: text/html
content-length: 16
date: Sun, 31 Oct 2021 14:26:12 GMT
last-modified: Sun, 31 Oct 2021 11:12:00 GMT
etag: "511ac4867e1719b448070e21caa3e54f-1"
x-amz-server-side-encryption: AES256
accept-ranges: bytes
server: AmazonS3
x-cache: Miss from cloudfront
via: 1.1 89a79abdcd1ed6464a36bc9e0c9decdc.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT12-C5
x-amz-cf-id: 0ey51T73RzUcdEV-pGSq2csrYcWtzRfnerNREt51byN2429iB5H7Pw==

path/index.html

まとめ: Lightsailのオブジェクトストレージをどう使うか

Lightsailのオブジェクトストレージ+CDNの構成で気になった点、CDNからオブジェクトストレージへの通信とアクセス許可、ならびにインデックスドキュメントの扱いについて確認してみました。CDNからオブジェクトストレージへの通信はHTTP固定、アクセス許可についてはCDNに関わらず公開が必要です。(いわゆるCloudFrontのOAIのような機能はありません。)またインデックスドキュメントについても設定ができません。

特にインデックスドキュメントの機能が使えない、という点では、単純な1枚のhtmlで構成されるようなページで「www.example.com」というシンプルな(ファイル名のパス部分がない)アドレスが使えない点が注意かと思いました。

しかし、そもそもLightsailのユースケースとしては、WordPressなどインスタンスでのホスティングを基本とし、その構成のサポートとしてオブジェクトストレージがある、という印象を持ちました。WordPressのプラグインでS3を使う代わりにLightsailのオブジェクトストレージを使う、というイメージですね。冒頭、Lightsailのマスコットくんがインスタンスの起動を進めてくれたのもそのためかもしれません。そのような背景もあり、オブジェクトストレージ単体でWebサイトをホスティングする機能までは、現段階では実装されていない状態なのかな、などと推測しています。

おまけ: オブジェクトストレージのCORS対応についてはどうか

もうひとつおまけとして、LightsailのオブジェクトストレージのCORS対応状況についても確認してみました。オブジェクトストレージへのアクセスの際、リクエストにOriginヘッダ付与されているケースでAccess-Control-Allow-Originヘッダなどが付与できるか、という点ですね。まずは通常のリクエストの際にOriginヘッダを付与して確認してみます。Access-Control-Allow-Originヘッダなどは確認できませんでした。

 % curl -I -H "Origin: https://www.example.com"  https://lightsail-bucket-XXXXXX.s3.ap-northeast-1.amazonaws.com/index.html
HTTP/1.1 200 OK
x-amz-id-2: ejikRaGMboS1s53496Kt9Fy+Tg15V+1NApUKffV2FZxyUPKRrC/xZ/+nkmh2jfs/EfJgX11XKoc=
x-amz-request-id: WEYF4PTAM7GT5ZYT
Date: Mon, 01 Nov 2021 02:30:40 GMT
Last-Modified: Sun, 31 Oct 2021 11:11:47 GMT
ETag: "49610d0b8cab2afecd6ef0c03fc1f4dd-1"
x-amz-server-side-encryption: AES256
Accept-Ranges: bytes
Content-Type: text/html
Server: AmazonS3
Content-Length: 11

Lightsailオブジェクトストレージの設定項目やドキュメントなどを確認してみましたが、CORSに関する記述は見つけられませんでした。オブジェクトストレージについては現段階ではCORS未対応のようです。ただしLightsailのCDNディストリビューションについては、Originヘッダをオリジンに転送する機能がありCORS対応がなされています。