概要
GitHubとAWS CodeBuildを組み合わせてVue.jsプロジェクトをビルドしてAWS S3に配置するまでを自動化します。
自動化のイメージとしては以下の流れ。
- GitHubへPush
- WebHook発火
- CodeBuild呼び出し
- ソース取得(git clone)
- ビルド(npm run build)
- 既存オブジェクト(資産)の削除
- デプロイ(dist/をS3へ配置)
CodePiplineは使いませんのでテストとかそういったたぐいは出てきません。
目次
環境
- AWS S3 + CloudFrontでホスティングされたVueプロジェクト
参考サイト様
- https://www.lanches.co.jp/blog/10249 🔗
buildspec.ymlを参考にさせていただきました。 - https://php-java.com/archives/2358 🔗
- https://techte.co/2017/04/09/cloudfront-create-invalidation/ 🔗
- https://qiita.com/uhooi/items/48ef6ef2b34162988295 🔗
- https://dev.classmethod.jp/cloud/codebuild-env/ 🔗
- https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-spec-ref.html 🔗
- https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/sample-github-pull-request.html 🔗
- https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/troubleshooting.html 🔗
- https://docs.aws.amazon.com/cli/latest/reference/s3/rm.html 🔗
0.前提
AWS S3でホスティングされたVueプロジェクトがあること。
(私の環境ではAWS S3 + CloudFrontの構成です。)
1.ビルドプロジェクトの作成
CodeBuildのビルドプロジェクト画面からCreate build project
を押下
以下の項目を設定しビルドプロジェクトを作成する。
直感的に設定できる内容かと思うので下記の項目設定はメモ程度で。
※記載の無い項目についてはデフォルト値とする。Project name
以外は作成後も変更可能。
- Project configuration
- Project Name: 適宜(今回は
SampleBuild
とする)
- Project Name: 適宜(今回は
- Source
- Source provider:
GitHub
を選択 - Repository:
Connect to GitHub
を押下しGitHubアカウントと紐付ける。(紐付け方式は好きな方を選択、今回はConnect using OAuth
を選択)- GitHubアカウント紐づけ後、項目が変化する。ビルド対象となるリポジトリを選択。
この際、URLで指定も可。自身のリポジトリについてはプルダウンから選択可。
- GitHubアカウント紐づけ後、項目が変化する。ビルド対象となるリポジトリを選択。
- Source provider:
- Primary source webhook events
- Webhook - オプショナル: チェックを入れると
Event type
を選択可能となる。 - Event type: 今回は
PUSH
を選択。
- Webhook - オプショナル: チェックを入れると
- Environment
- Environment image:
Managed image
を選択。Custom image
を選択することで任意のDocker imageを選択可能。
特に開発環境と本番環境をあわせたいと言う思いもないので今回はManaged image
を使用する。
- Operation system:
Ubuntu
を選択。てかこれしかない。 - Runtime:
Node.js
を選択。 - Runtime version:
10.14.1
を選択。選択した理由は特にない。 - Service Role: 適宜
- Environment image:
- Buildspec
- Build specifications:
Use a Buildspec file
を選択。Use a Buildspec file
:リポジトリに登録されているbuildspec.yml
を使用。Insert Build commands
:CodeBuildの画面上でbuildspec.yml
を編集可能。
最初の動作確認はこっちのほうがてっとり速く編集できて楽かも、ただエディタがあまりよろしくないのでローカルで書くことをおすすめする。
- Build specifications:
- Artifacts ※(ビルドした)成果物の配置先
- Type:
Amazon S3
を選択。 - Bucket name: 適宜選択。
- Name - オプショナル:
/
を入力。(※バケット直下にindex.html
を配置しているため。example.com/index.html
のような想定) - Path - オプショナル:
/
を入力。同上 - Artifacts packaging:
なし
を選択。今回は小さなサイトをデプロイする想定なのでZipで固めたりはしない。 - Remove artifact encryption: チェックを入れる。
- Type:
- Logs 適宜設定すること。
2.buildspec.ymlの作成・追加
Buildspec.ymlについては下記のコードを使用。
下記のコードをbuildspec.yml
としてプロジェクトフォルダの直下に配置しリポジトリにも反映する。
※1.プロジェクト作成時にInsert Build commands
を選択した場合はブラウザのテキストエディタにコピペ
※2.インデントにはTAB文字は使えない。半角スペースを使用すること。
version: 0.2
# GitHub -> CodeBuild -> S3 -> CloudFront
phases:
install:
commands:
- echo update npm...
- npm install -g n
- n latest
- npm update -g npm
- echo node -v
- node -v
- echo npm -v
- npm -v
pre_build:
commands:
- echo Installing source NPM dependencies...
- npm install
build:
commands:
- echo build start
- npm run build
- echo build completed
post_build:
commands:
- echo Delete S3 Bucket object...
- aws s3 rm s3://${S3_BUCKET_NAME} --recursive
- echo create invalidation
- aws cloudfront create-invalidation --distribution-id ${CLOUDFRONT_DISTRIBUTION_ID} --paths '/*'
artifacts:
files:
- "**/*"
base-directory: "dist"
環境変数について
${S3_BUCKET_NAME}
と${CLOUDFRONT_DISTRIBUTION_ID}
については環境変数としてプロジェクトに登録しています。
ビルドプロジェクト画面Build details
タブのEnvironment
から編集可能です。
また、入力
項目はPlaintext
としています。Parameter
とした場合、別設定が必要になります。
(よく知らないですが秘匿する必要のあるアクセスキー等はParameterで暗号化して使用するそうです。)
buildspec.ymlコマンドの解説
ただ、サーバ上で実行しているコマンドの羅列なので特に解説は必要ないと思うが独自要素についてメモとして記述する。
S3バケット内の既存資産(オブジェクト)の削除
過去にビルドし配置されたファイルの削除を行う。
使用しているロールへポリシーの追加が必要。
IAMよりS3のDeleteObject
権限を追加すること。
aws s3 rm s3://${S3_BUCKET_NAME} --recursive
awsコマンドについては参考リンクを参照のこと。
CloudFrontのInvalidationの作成
S3 + CloudFrontの構成であるため配置された資産がキャッシュされている。アップロードした資産を即時反映するためには都度キャッシュの削除が必要である。
そのためInvalidationを作成してキャッシュを削除し即時反映させる。
こちらもロールへのポリシーの追加が必要。IAMより該当ロールにCloudFront
のCreateInvalidation
権限を追加すること。
aws cloudfront create-invalidation --distribution-id ${CLOUDFRONT_DISTRIBUTION_ID} --paths '/*'
※ネットで見かけたレベルの話ではあるかLambda FunctionでもInvalidation
の実装は可能な模様。
artifactsの指定
デプロイする成果物(ビルドで作成されたファイル)を指定する。
artifacts:
files:
- "**/*"
base-directory: "dist"
files: - '**/*'
でディレクトリ配下全てをデプロイする資産として指定する。
ただしこのままではプロジェクトディレクトリ配下全てが指定されてしまうため、base-directory
でdist
ディレクトリを指定する。
こうすることでdist
配下のファイルをデプロイするファイルとして指定することができる。
閑話休題
上述のartifacts
の指定でbase-directory
を指定せずにfiles: - '**/*'
を記述したためプロジェクトディレクトリ配下全てがS3にデプロイされる事態となった。
node_module
とか全てwwww
デプロイが全く終わらなくて辛かった。
3.ビルドの実行
ブラウザの画面からStart build
、もしくはリポジトリにPUSHしてWebhookを発火させて試してね。
Github WebhookとBuild projectのEvent発火タイミングについて
イマイチまだ実際の動作とか理解できてなくてとりあえずPUSHしとけみたいなノリです。
全然調べたとかじゃないんですがWebhookとBuild project側のEvent typeってどちらが優先されるんですかね。よくわかんないですけど。
そのうち調べようと思います。
トラブルシュート
詰まりどころを何点か
S3バケットの直下にビルドしたファイルが配置されない。
ビルドプロジェクト画面Build details
タブのArtifacts
(buildspec.ymlの方じゃないよ)を見直す。
想定したパスを指定しているか否か。空欄となっていないかなど確認する。
デプロイうまく行ったのにサイトに繋がらない。
ビルドプロジェクトの暗号化設定を確認する。
ビルドプロジェクト画面Build details
タブのArtifacts
から確認可能。
Remove artifact encryption
にチェックが入っていることを確認する。
また、暗号化されているか否かはS3バケットの該当ファイルをクリックすることでプロパティから確認可能。
雑感
いちいちローカルでビルドしてS3の画面でドラッグ&ドロップでアップロードしてってのが面倒臭くてやった。
Buildspec.ymlのArtifactsってのが全然理解できなくて試しながらでやったので時間がかかった。
今度はホントのアプリケーションを作ってPipelineつかって自動テストとか回してみたいですね。