CodePipelineでS3にデプロイしてCloudFrontでコンテンツを配信する

CodeStarでさくさくCI/CD作りもいいのだが、とりあえず一旦はCodeCommitからDeployまでCodePipelineで連携する方法を理解しておこうと思ったので、軽く試してみた。

CloudFrontで配信するところまでやってみる。

やること

  • CodePipelineを利用して、CodeCommit, CodeBuildを連携させ、ReactクライアントをS3にアップロードする(デプロイ)。
  • S3に配置されたReactクライアントをCloudFrontで配信する。

やる順番

  1. CodeCommitでリポジトリを作成
  2. CodeBuildでビルドの設定(テストの設定とかはしない)
  3. CodePipelineでCommitからDeployまでを一貫して行う(S3へビルドファイルをアップロード)
  4. CloudFrontでコンテンツを配信(細かい設定はしない)

CodeCommitでリポジトリを作成

AWSコンソールのCodeCommitを開き、リポジトリを作成する。

仮にリポジトリ名testを作成すると以下のような「接続のステップ」が表示される。

Screenshot 0032-01-14 at 10.14.19 PM.png

ソースコードをプッシュするには、まずこのリポジトリをクローンする必要がある。 右上の「URLのクローン」から「HTTPSのクローン」を選択すると、URLがコピーされるのでローカルでgit cloneする。

git cloneの際に尋ねられるユーザー名等はIAMの認証情報から取得する。 IAMのアクセス管理>ユーザーからアカウントを選択して、「AWS CodeCommit の HTTPS Git 認証情報」の「認証情報を生成」から証明書をダウンロードする。

中のユーザー名とパスワードを使ってgit cloneできるようになる。

cloneしたディレクトリにソースコードを置いてプッシュすればCodeCommitにソースコードが表示される。

CodeBuildでビルドの設定

AWSコンソールのCodeBuildを開き、ビルドプロジェクトを作成する。

公式の解説ページも参考に。 CodeBuild でビルドプロジェクトを作成する

「ビルドプロジェクトを作成」へ入ると、

の設定項目が目につくが、ここでは「送信元」、「環境」、「Buildspec」のみに触れる。

アーティファクト」と「ログ」の設定は触れずにビルドプロジェクトを作成する。

CodeBuild 送信元設定

Screenshot 0032-01-14 at 10.39.50 PM.png

ここで指定するソースプロバイダは、CodeCommitの入力アーティファクトを出力するソースコードを指す。

CodePipeline(CodeCommit, CodeBuild, CodeDeployをCI/CD機能)では入力アーティファクトと出力アーティファクトが各フェイズで受け渡される。 アーティファクトとはそれぞれのフェイズの成果物のことで、CodeCommitの出力アーティファクトはコードそのものであり、CodeBuildはそれを入力アーティファクトとして受け取って、ビルドしたファイルを出力アーティファクトとしてCodeDeployへ渡す。

入力および出力アーティファクト

CodeBuild 環境設定

Screenshot 0032-01-14 at 10.56.50 PM.png

ビルド環境設定では、ビルドを実行するためにCodeBuildが使用するオペレーティングシステムプログラミング言語ランタイム、およびツールの組み合わせを設定することができる。

特にこだわりがないのであれば、 OS、ランタイム、イメージ、イメージのバージョン、環境タイプは上記のように設定すればたいして困らないと思う。

サービスロールではCodeBuildの実行に必要なポリシーが組まれたロールが作成される。 すでにある場合は既存のものを使える。

CodeBuild のビルド環境リファレンス CodeBuild に用意されている Docker イメージ

CodeBuild Buildspec設定

Screenshot 0032-01-14 at 11.25.09 PM.png

ビルドコマンドの挿入の選択肢もあるが、ここではbuildspecファイルを使ったビルド設定について触れる。 ここまでにCodeBuildがビルドを行うソースコードの設定と、ビルドを行う環境の設定について書いたが、Buildspecではビルドの実行時に実行する細かい処理についての設定を行うことができる。

例えば、reactクライアントをCodeCommitへのプッシュをトリガーとしてビルドしたい場合は、以下のようにディレクトリ内にbuildspec.ymlを配置する。

Screenshot 0032-01-14 at 11.32.04 PM.png

これがこのリポジトリのルートディレクトリだとすると、Buildspecの項目におけるBuildspec名にはファイルそのものを指定すれば良い。 もしリポジトリ内の特定のディレクトリに存在するBuildspecファイルを指定したい場合は、そのパスを書く(client/buildspec.ymlのように)。

また、このymlファイルの名前がbuildspecである必要はない(clientspec.ymlとかでも良い)。

buildspec.ymlの例 例ではreactクライアントのビルドを念頭に置いているため、runtime-versionsはnodejs10.xを指定しており、 typescriptをインストールしている。

version: 0.2

phases:
  install:
    runtime-versions:
      nodejs: 10
    commands:
      - npm install -g typescript
  pre_build: # ビルド実行前に実行する処理等の設定
    commands:
      - cd client
      - npm install
  build: # ビルド実行処理等の設定
    commands:
      - npm run build
  # post_build:
  #   commands:
  #     - some command
  #     - some command
artifacts:
  files:
    - 'client/dist/*' # 出力するビルドファイル
  discard-paths: yes # 出力するビルドファイルからパスを省く(client/dist/などを省く)

CodeBuild のビルド仕様に関するリファレンス

CodePipelineでCommitからDeployまでを一貫して行う

AWSコンソールのCodePipelineを開き、パイプラインを作成する。

パイプライン名とサービスロールを設定すると、

  • ソースステージ
  • ビルドステージ
  • デプロイステージ

の設定に入る。

ソースステージの設定

Screenshot 0032-01-14 at 11.54.58 PM.png

CodeCommitのリポジトリ名とブランチ名を指定する。 これはビルドステージへの出力アーティファクトとなる。

ビルドステージの設定

Screenshot 0032-01-14 at 11.57.00 PM.png

CodeBuildで設定したプロジェクトを指定する。

デプロイステージの設定

Screenshot 0032-01-15 at 12.01.07 AM.png

CodeDeployはS3のデプロイに対応していないため、S3デプロイを行うためにはCodePipelineを使う必要がある。

デプロイプロバイダーにS3を指定し、デプロイ先のバケットを選択する。 ここでは「デプロイする前にファイルを抽出する」にチェックを入れている(何もしないとzipがバケットに配置されるが、ここでは解凍された状態で配置したいため。デプロイパスはバケット内に展開されるディレクトリの構成を設定できる)。

全ての設定を終えて確認画面から「パイプラインを作成する」と、パイプライン一覧に新規パイプラインが表示される。 ソースコードに変更を加え、CodeCommitへプッシュすると、自動的にCodeBuildが起動し、S3へのビルドファイルのデプロイが行われる。

デプロイ設定で指定したバケット内にビルドしたファイルが表示されるはず。

Screenshot 0032-01-15 at 12.07.45 AM.png

CloudFrontでコンテンツを配信

CloudFrontとはオリジンサーバーが直接アクセスに対応する機会を減らし、キャッシュ化されたエッジロケーションのリソースに対してユーザをルーティングする機能のこと。 Amazon CloudFront とは

AWSコンソールでCloudFrontを開き、CreateDistributionを選択する。

Screenshot 0032-01-15 at 11.33.52 PM.png

WebのGet Startedからディストリビューションの設定を行う。

Origin Settingでは以下の2点を設定する。

  • Origin Domain Name CodePipelineでビルドファイルをデプロイしたS3バケットを選択する。

  • Restrict Bucket Access バケットのリソースへのアクセスを、S3のURLを使わずに常にCloudFrontのURLを利用したアクセスのみに絞りたい場合はこの項目をYesに設定する。

Default Cache Behavior Settingsは飛ばして、 Distribution Settingsでは以下の項目だけを設定する。

  • Default Root Object
    index.htmlを指定する。 これはバケット内のインデックスドキュメントの設定。 設定しないと${URL}/index.htmlとしてアクセスしなければならない。

Create Distributionをクリックして一覧に表示されるディストリビューションのStatusがDeployedになるまで待つ。

Screenshot 0032-01-15 at 11.44.21 PM.png

DeployedとなったらDomain Nameに表示されているURLにアクセスしてページが動いているかを確認する。

完。

まとめ

ここまででCodeCommitに新しい変更をコミットしていくと、S3バケットに自動的にビルドファイルがアップロードされるようになる。

厳密なデプロイはそのあとにCloudFrontのディストリビューションのInvalidate(CloudFrontのエッジロケーションのキャッシュを削除して更新されたコンテンツを再配布する)を行ったときに行われる。

InvalidateはCloudFrontのディストリビューションの一覧画面からディストリビューションを選び、Invalidationタブを選択した画面で行える。

Screenshot 0032-01-15 at 11.55.39 PM.png

Create InvalidationからInvalidateする項目を指定してInvalidateボタンをクリックするだけ。 バケット内の全てのファイルを指定してInvalidateする場合は*(アスタリスク)を指定すれば良い。

今後デプロイの手順としては、

  1. CodeCommitへコードのプッシュ
  2. CloudFrontでInvalidateを実行

をするだけでよくなる。

おしまい。