はじめに
TeQAというサービス開発を通して得た知見を記載していこうと思います。
TeQA内で使用しているserverless framework componentsを用いたデプロイとS3の設定についてです。
serverless framework componentsでのwebsite deploy
serverless framework componentsを用いて、websiteをビルドしS3へのデプロイを行っています。
serverless framework componentsは下記のようなserverless.ymlのみを配置し、ドメインネームのみ申請すればonelineで、S3の設定やデプロイなど多くのことをやってくれるすごいやつです。
component: website
name: hoge
stage: dev
inputs:
src:
src: ./src
hook: yarn build
dist: ./build
domain: ${custom.${stage}.domain}
region: ap-northeast-1
custom:
dev:
domain: hoge.com
test:
domain: test.hoge.com
prod:
domain: hoge.com
そのため、React用のアプリケーションをCreate-React-Appで作成し、上記のserverless.ymlを配置し、ドメインネームを取得すれば、
$ serverless deploy --stage dev
で、すぐにAWS上にデプロイ可能です。
ただ使っていく中でプロダクション向けには、別途設定しなければならない箇所が出てきました。
S3へのメタデータ設定が付与できない
S3でSPAを配置するときは、ブラウザ側の読み込み速度を考慮しcache-controlなどのメタデータを付与したいものです。
ただ、serverless frameworkではそのようなS3オブジェクトへの細やかな設定付与はどうやらできないようなので、別途スクリプトを用意してやる必要があります。
S3への配置でキックされるLambda関数等を用意してもよいのですが面倒なので、今回はaws cliでシェルスクリプトを書いてしまいます。
下記が完成形になります。
# !/bin/bash
BUCKET_NAME="hoge"
PROFILE_NAME="profile"
CACHE_CONTROL="max-age=xxxxxxx"
for key in $(aws s3 ls $BUCKET_NAME --recursive --profile $PROFILE_NAME | sed -E 's/[\t ]+/ /g' | cut -d " " -f 4); do
ContentType=$(aws s3api head-object --bucket $BUCKET_NAME --key $key --profile $PROFILE_NAME | jq '.ContentType')
# echo $ContentType | sed 's/"//g'
aws s3 cp s3://$BUCKET_NAME/$key s3://$BUCKET_NAME/$key --metadata-directive "REPLACE" --content-type $(echo $ContentType | sed 's/"//g') --cache-control $CACHE_CONTROL --acl public-read --profile $PROFILE_NAME
done
簡単に解説していくと、
aws s3 ls $BUCKET_NAME --recursive --profile $PROFILE_NAME
これでawsのbucket内のオブジェクトkeyを取得します。
その後に、s3apiのhead-objectを用いて、serverless deploy時に自動設定されるcontent-typeを取得します。
aws s3api head-object --bucket $BUCKET_NAME --key $key --profile $PROFILE_NAME
最後に、取得したcontent-typeと定義したcache-controlでS3 objectを上書きしていきます。
aws s3 cp s3://$BUCKET_NAME/$key s3://$BUCKET_NAME/$key --metadata-directive "REPLACE" --content-type $(echo $ContentType | sed 's/"//g') --cache-control $CACHE_CONTROL --acl public-read --profile $PROFILE_NAME
aws cliでs3 objectに対してcache-controlをつける際は、REPLACEオプションのみを受け付ける仕様で、さらにREPLACEオプションをつけてしまうと既存のメタデータが全て上書きされてしまいます。
そのためこのように
- 既存のメタデータ取得
- 既存のメタデータと追加したいメタデータを付与してobject更新
という少し手間がかかる方法で更新しています。
おわりに
serverless frameworkですが、Serverlessなものに特化して非常に使い勝手位の良いフレームワークになっています。
AWSでインフラ構成だとcloud formation/terraformになりがちだと思いますが、サーバーレス系のマネージドサービスを小さく素早く使うには充分なものだと思いました。