2018-12-20

超今さらS3 + CloudFront + CloudFormationでWebサイトを公開する設定についてOriginとProtocolの注意点

※ 独自ドメイン関係の話は一切ないです。あくまで公開できる状態になるまでで S3 Web Site Hosting と CloudFront の Origin の設定と Protocol の話のみです。

S3はWeb Site Hostingにすべし

最近は AWS 側で不必要に S3 Bucket を公開してしまわないように Web UI でいろいろ警告してくれるというか分かりやすくしてくれていて、「もしかして S3 の Web Site Hosting って実は使ってほしくないのかな?」という雰囲気を感じていたんだけど、どうもそういう意図はないらしい。うっかりを防ぎたいだけっぽい。

というのも、

Web Site Hosting にしておかないと IndexDocument などの機能が効かないので / で終わる Directory へのアクセスは不可能

だから。

※ 逆に、 / で終わる URI が世界に共有されないのであれば Web Site Hosting でなくてもよい。

cf. ウェブサイトエンドポイント - Amazon Simple Storage Service

CloudFrontからS3へCustom Originで繋ぐ

CloudFront から S3 を見にいく場合、S3 Origin としてアクセスしにいくか Custom Origin としてアクセスしにいくかを選べる。

結論から言うと上と同じ理由で

Web サイトとして S3 を使う場合は Custom Origin にする

のが正解。S3 Bucket としてではなくただの Web サイトとしてアクセスしにいく方式だ。

そのため、DomainName の設定は

<bucket-name>.s3-website-<region>.amazonaws.com

にしておく必要がある。

S3 Origin としてアクセスする方式でも asset や upload 済みの「ファイルだけにアクセスさせる」場合は問題ないのだが、「HTTP でリソースにアクセスできることと Web サイトとしてアクセスできることの意味は異なる」ところがポイント。

例えば上のように / で終わる URI に対して CloudFront にアクセスがあった場合、CloudFront は S3 に対してもまったく同じように / というリソースを要求するのだが、これは S3 Object としては存在しない。あくまで S3 上では Object として存在しているのではなく Prefix として機能しているだけなので、これにアクセスすることはできないのだ。

※ トップページ / に対してだけは DefaultRootObject を設定できるのがまた事態をややこしくしている。これは本当にトップの / に対してだけしか効かない。

もし / で終わる URI にアクセスできているとしたら、それは Web Site Hosting 機能の IndexDocument のおかげである。そして Web Site Hosting に対して CloudFront からリクエストするためには Custom Origin にしておく必要がある。

ウェブサイトエンドポイント - Amazon Simple Storage Service

仕上げにCloudFrontからS3へはhttp-onlyで繋ぐ

CloudFront は Origin を複数設定できるのだが、CloudFormation の設定を YAML で書くとすると、

Origins:
  - Id: <Name>
    CustomOriginConfig:
      OriginProtocolPolicy: http-only

としておくのが正解。

CustomOriginConfig では OriginProtocolPolicy が required なのでこれを http-only にしておく。

順番に見ていくと、

  • Origins の設定のところには S3OriginConfig か CustomOriginConfig のいずれかが required
  • S3 Website Hosting に接続するには CustomOriginConfig が required
  • CustomOriginConfig を設定するためには OriginProtocolPolicy が required

という寸法。

S3のWeb Site Hostingはhttp-only

ウェブサイトエンドポイント - Amazon Simple Storage Service

S3 の Web Site Hosting の機能で提供されるのは上の「ウェブサイトホスティング」に該当する。

ということは「SSL 接続をサポートしません」なので、上のように

Origins:
  - Id: <Name>
    CustomOriginConfig:
      OriginProtocolPolicy: http-only

で http-only にしておくのが正解。これで CloudFront へのアクセスが http でも https のどちらであっても、S3 へは http で接続しにいく。

これを指定しておかずにうっかり https でリクエストすると謎の timeout に苦しむことになる。

cf.

おまけ

CloudFormation を使えば確かに設定をコードで管理できるようにはなるが、決してお手軽に設定できるわけではない。

その設定になる理由はすべて資料と現象の観測と収集できる情報から掘り下げていくしかない。

例えば CloudFront で /path/to/resource/ へアクセスすると timeout するが /path/to/resource/index.html へアクセスすれば ok 、http ではアクセスできて https でアクセスできない、といったことは順番に試して現象を観測して分類、整理して解決していくしかない。

そうたくさんくり返すわけでもないこの手の作業こそ基本が大切。

About

例によって個人のなんちゃらです

Recent Posts

Categories

Tool 日々 Web Biz Net Apple MS ことば News Unix howto Food PHP Movie Edu Community Book Security Text TV Perl Ruby Music Pdoc 生き方 RDoc ViewCVS CVS Rsync Disk Mail FreeBSD Cygwin PDF Photo Zebedee Debian OSX Comic Cron Sysadmin Font Analog iCal Sunbird DNS Linux Wiki Emacs Thunderbird Sitecopy Terminal Drawing tDiary AppleScript Life Money Omni PukiWiki Xen XREA Zsh Screen CASL Firefox Fink zsh haXe Ecmascript PATH_INFO SQLite PEAR Lighttpd FastCGI Subversion au prototype.js jsUnit Apache Trac Template Java Rhino Mochikit Feed Bloglines CSS del.icio.us SBS qwikWeb gettext Ajax JSDoc Rails HTML CHM EPWING NDTP EB IE CLI ck ThinkPad Toy WSH RFC readline rlwrap ImageMagick epeg Frenzy sysprep Ubuntu MeCab DTP ERD DBMS eclipse Eclipse Awk RD Diigo XAMPP RubyGems PHPDoc iCab DOM YAML Camino Geekmonkey w3m Scheme Gauche Lisp JSAN Google VMware DSL SLAX Safari Markdown Textile IRC Jabber Fastladder MacPorts LLSpirit CPAN Mozilla Twitter OpenFL Rswatch ITS NTP GUI Pragger Yapra XML Mobile Git Study JSON VirtualBox Samba Pear Growl Mercurial Rack Capistrano Rake Win RSS Mechanize Sitemaps Android JavaScript Python RTM OOo iPod Yahoo Unicode Github iTunes God SBM friendfeed Friendfeed HokuUn Sinatra TDD Test Project Evernote iPad Geohash Location Map Search Simplenote Image WebKit RSpec Phone CSV WiMAX USB Chrome RubyKaigi RubyKaigi2011 Space CoffeeScript Nokogiri Hpricot Rubygems jQuery Node GTD CI UX Design VCS Kanazawa.rb Kindle Amazon Agile Vagrant Chef Windows Composer Dotenv PaaS Itamae SaaS Docker Swagger Grape WebAPI Microservices OmniAuth HTTP 分析基盤 CDN Terraform IaaS HCL Webpack Vue.js BigQuery Middleman CMS AWS PNG Laravel Selenium OAuth OpenAPI GitHub UML GCP TypeScript SQL Hanami Document SVG AsciiDoc Pandoc DocBook Develop Jekyll macOS Node.js Vite Heroku Transformer AI Data Cloud Wasm