TL;DR
- CodeBuild のアーティファクトを S3 に配置すると AWS-KMS で暗号化され、
Content-Type: binary/octet-stream
がメタデータに付与される。 - アーティファクトに HTML などを含み、それをそのまま静的ウェブサイトとしてホストするには、 AWS cli を使って自分で S3 に cp する必要がある。
背景
parcel-bundler などのツールを使って静的な Web サイトを書いたので、それを S3 を使って配信したい。配信まわりの作業を自動化するために CodeBuild を使うことにした。
ダメだったやり方
CodeBuild はビルド結果をアーティファクトとして(入力と区別するためにこれを "出力アーティファクト" と明示する場合もある) S3 などに自動的に配置する機能がある。 アーティファクトとして HTML を CodeBuild で S3 に配置するには以下のような buildspec.yml をプロジェクトルートに設置する。
version: 0.2
phases:
install:
commands:
- npm install
pre_build:
commands:
- npm test
build:
commands:
# `npm run build` すると dist ディレクトリに静的ファイルが生成されるとする
- npm run build
artifacts:
files:
- '**/*'
base-directory: dist
その上で CodeBuild のビルドプロジェクトの "アーティファクト" の "タイプ" 項目で "AWS S3" を選択し、ビルドを実行すると、たしかに dist ディレクトリ以下のファイルが全て指定した S3 バケットに設置されている。
しかし、これらのファイルは全て AWS-KMS で暗号化されているため、都度複合キーを指定しなければ静的ファイルとしてアクセスすることができない。また Content-Type が octet/steam なのでブラウザが正しく解釈することができない。
AWS CLI を使う
アーティファクトを使えないので、自分で S3 に移動させる必要がある。
version: 0.2
phases:
install:
commands:
- npm install
- pip install --upgrade awscli
pre_build:
commands:
- npm test
build:
commands:
- npm run build
post_build:
commands:
- aws s3 cp --recursive dist/ s3://$WEBSITE_S3_BUCKET/ --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers
S3 バケットの名前は WEBSITE_S3_BUCKET
という環境変数として指定する。バケットにはパブリックアクセス権限を持たせず、コピーするファイルに都度権限を設定しているので(--grants read=...
)、 PutObject
だけでなく PutObjectAcl
権限が必要となる。