AWS Elemental MediaStoreでCORSを設定してみた

2018.04.30

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

清水です。AWS Media Servicesの1つでメディア向けに最適化されたストレージであり、またS3よりも強い整合性を持つという特徴ももつAWS Elemental MediaStoreですが、CORS(Cross-Origin Resource Sharing)をポリシーにより設定できる機能があります。2017年11月末のAWS Elemental MediaStoreリリース時には設定項目がなかったのですが、2018年2月の機能アップデートにより設定可能となりました。

今回はこのAWS Elemental MediaStoreのCORSポリシーを設定してみたので、まとめてみます。

やってみた

CORS設定が影響するケースとしないケース

AWS Elemental MediaLiveと連携して、AWS Elemental MediaStoreをエンドポイントとしてライブ配信を行う構成を考えます。(実際にはMediaStoreがオリジン、Amazon CloudFrontなどCDNを経由して配信する構成となるかと思います。この場合、本エントリのオリジンに対するCORS設定を元に、CDNについて適切に設定しましょう。)

MediaStoreのエンドポイント、例えば以下のURLからライブ配信ができると仮定します。

  • https://xxxxxxxxxxxxx.data.mediastore.ap-northeast-1.amazonaws.com/live/hls.m3u8

HLS形式の配信にネイティブ対応する、例えばSafariなどのブラウザからこのエンドポイントを直接参照する場合は、CORSの設定の有無にかかわらず、特に問題なく再生ができます。(CORS設定が影響しないケース)

対して、Video.jsなどhtml/JavaScriptファイルを別ドメインでホストして、映像配信部分のみJavaScriptなどからMediaStoreを参照するケースでは、MediaStoreのCORS設定を行っていないと、「Access-Control-Allow-Originヘッダがない」などとと問題になってしまいます。例えばVideo.jsのvideojs-contrib-hlsを使った場合では以下のように(Google Chromeのデベロッパーツールでは)Consoleで警告が発せられ、動画の視聴ができませんでした。

AWS Elemental MediaStoreでCORSを設定する

AWSマネージメントコンソールからMediaStoreにCORSを設定してみます。MediaStoreのコンテナ(=S3のバケットのイメージ)毎にCORSポリシーとして設定することができます。コンテナ一覧画面からCORSを設定するコンテナの詳細画面に進みます。画面一番下に"Container CORS policy"の欄があります。[Create CORS policy]ボタンで設定画面に進みます。

CORSポリシーの書き方はドキュメントの例を参考にしましょう。

今回はどのドメインからもReadを許可するポリシーを設定してみます。

ドキュメントに従い、以下のをポリシーとして設定します。

[
  {
    "AllowedHeaders": [
      "*"
    ],
    "AllowedMethods": [
      "GET",
      "HEAD"
    ],
    "AllowedOrigins": [
      "*"
    ],
    "MaxAgeSeconds": 3000
  }
]

[Save]ボタンで設定を保存します。反映まで少し時間がかかることがあるので注意しましょう。

設定反映後、例えば先ほどのVideo.jsのvideojs-contrib-hlsで確認すると、「Access-Control-Allow-Originヘッダがない」と表示されていた警告はなくなり、動画が再生されます。

CORS設定後のレスポンスヘッダの変化を確認してみる

CORS設定前後の、MediaStoreのレスポンスヘッダについても確認してみます。まずは設定前のレスポンスヘッダです。CORSとなるように-HオプションでOriginヘッダをつけて確認します。Video.jsでアクセスした際に「Access-Control-Allow-Originヘッダがない」と言われていたとおり、このAccess-Control-Allow-Originヘッダはありませんね。

 $ curl -I -H"Origin: https://akibaaws5.example.com.info" https://xxxxxxxxxxxxx.data.mediast
ore.ap-northeast-1.amazonaws.com/live/hls.m3u8
HTTP/1.1 200 OK
x-amzn-RequestId: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXI3PVUCJY63OLEDXT3PED5NMTDOHISFAV4NXCHL6TX3KRWK3ITQQO6N
Last-Modified: Mon, 30 Apr 2018 05:30:01 GMT
Cache-Control: max-age=3
ETag: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac71f7007f8458e88e75baea20150674d
Content-Type: application/vnd.apple.mpegurl
Content-Length: 726
Date: Mon, 30 Apr 2018 08:05:38 GMT

続いて、MediaStoreに先ほどのどのドメインからもReadを許可するCORSポリシーを設定してみた場合です。こちらもCORSとなるように-HオプションでOriginヘッダをつけて確認します。Access-Control-Allow-Originヘッダ、Varyヘッダ、Access-Control-Expose-Headersヘッダが追加されていることがわかります。

 $ curl -I -H"Origin: https://akibaaws5.example.com.info" https://xxxxxxxxxxxxx.data.mediastore.ap-northeast-1.amazonaws.com/live/hls.m3u8
HTTP/1.1 200 OK
x-amzn-RequestId: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXJRTGVQDVRBTX6JDJ52SMDTUYGMGQD4RVFPYBHCLTJSKVXQQNVBVOOQQ
Last-Modified: Mon, 30 Apr 2018 05:22:20 GMT
Access-Control-Allow-Origin: https://akibaaws5.example.com.info
Cache-Control: max-age=3
Vary: Origin
ETag: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac71f7007f8458e88e75baea20150674d
Access-Control-Expose-Headers: x-amzn-ErrorMessage,Cache-Control,Content-Range,ETag,x-amzn-RequestId,x-amzn-ErrorType,Last-Modified,Content-Length,Date,Content-Type
Content-Type: application/vnd.apple.mpegurl
Content-Length: 726
Date: Mon, 30 Apr 2018 08:06:19 GMT

まとめ

AWS Elemental MediaStoreでCORSポリシーを設定をしてみました。MediaStoreにCORS設定もできるので、よりS3のように(そしてS3よりも整合性の強いストレージとして)使えるのではないでしょうか。なおS3へのCORS設定については下記エントリもご参照ください。

MediaStoreを動画配信用のストレージとして利用し、Video.jsなどJavaScriptを用いたPlayerを使用する場合には、本エントリで扱ったCORS設定を確認しましょう。またMediaStoreはオリジンとして扱い、Amazon CloudFrontなどCDNを介してエンドユーザに配信することが推奨されています。合わせて使用するCDNでCORSをどう扱うかも確認が必要です。Amazon CloudFrontをCDNに使用する場合は下記エントリが参考になるかと思います。