CodeBuild artifacts は AWS-KMS + binary/octet-stream として S3 に配置される


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 をプロジェクトルートに設置する。

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 に移動させる必要がある。

buildspec.yml
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 権限が必要となる。