7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CodeCommitからS3バケットへファイルを自動配信する

Posted at

#概要
CodeCommitの特定ブランチにプッシュがあったとき、S3バケットへファイルを自動配信する。
CodeCommit2S3.png

##実現する内容

  • 追加または変更されたファイルだけを配信する(変更のないファイルは配信しない)
  • ブランチから削除されたファイルは配信先バケットからも削除する
  • ブランチごとに配信先バケットを切り替える

##利用するサービス

  • Amazon S3
  • AWS Codecommit
  • AWS CodeBuild
  • AWS Lambda

##処理の流れ

  1. CodeCommitにプッシュがあったときLambdaを呼び出す
  2. Lambdaでブランチを指定してCodeBuildを呼び出す
  3. CodeBuildが指定ブランチをクローンする
  4. CodeBuildでgit-set-file-timesを実行する
  5. CodeBuildでaws s3 syncを実行する

#構築
AWSで各サービスを設定する。

##前提条件

  • Codecommitにリポジトリを作成してあること
  • S3に配信先バケット(本番バケットおよび開発バケット)を作成してあること
  • アクセス権限は適切に設定しておくこと

##CodeCommit

###ブランチ構成

ブランチ 配信先バケット
master 本番バケット
develop 開発バケット

###ディレクトリ構成

├─ buildspec.yml            # buildspecファイル
├─ git-set-file-times.pl    # git-set-file-timesソースコード
└─ contents                 # S3に配信するファイルを格納したディレクトリ
  ├─ index.html
  :
  :

####buildspec.yml

buildspec.yml
version: 0.2

phases:
  pre_build:
    commands:
      # ブランチ名を取得
      - branch=`git branch --contains | grep -v '(no branch)' | cut -b 3-`
      # ブランチ名から配信先バケットを判断(ブランチ名が不正の場合は中断)
      - case "$branch" in
          "master"  ) bucket=<本番バケット名> ;;
          "develop" ) bucket=<開発バケット名> ;;
          *         ) exit 1 ;;
        esac
  build:
    commands:
      # ファイルのタイムスタンプをコミット時刻に変更
      - perl git-set-file-times.pl
      # 対象バケットにファイル配信
      - aws s3 sync --exact-timestamps --delete contents s3://$bucket

####git-set-file-times.pl
Git公式Wikiのサンプルスクリプトを使う。

##CodeBuild
###ビルド作成
送信元
Gitのクローンの深さ(=depth)をFullに設定する。
qiita01.png

環境
イメージはaws/codebuild/standard:1.0を選択する。 ※runtime-versions未設定のため
qiita02.png

##Lambda
###関数作成
ランタイムは「Node.js 10.x」または「Node.js 8.10」で作成する。

index.js
const AWS = require('aws-sdk');
const codeBuild = new AWS.CodeBuild();

exports.handler = async (event) => {
  const param = {
    projectName: "sample-build",
    sourceVersion: event.Records[0].codecommit.references[0].commit
  };
  await codeBuild.startBuild(param).promise();
};

###トリガ作成
CodeCommitからも作成可能だが、ここではLambdaの「トリガーの追加」から作成する。
qiita03.png

#解説
構築の意図を記載する。

##ファイル配信について
CodeBuildでS3バケットにファイル配信するためにAWS CLIコマンドを実行する。

aws s3 sync --exact-timestamps --delete contents s3://$bucket

--exact-timestampsはローカルファイルのタイムスタンプがS3より新しい場合に上書きするオプション、--deleteはローカルファイルが存在しなければS3からも削除するオプションである。この2つのオプションで以下の2点を実現できる。

  • 追加または変更されたファイルだけを配信する(変更のないファイルは配信しない)
  • ブランチから削除されたファイルは配信先バケットからも削除する

ただし、Gitの仕様上、ローカルファイルのタイムスタンプはチェックアウト時刻になるので、git-set-file-timesスクリプトでコミット時刻に変更しておく必要がある。このスクリプトはローカルリポジトリのコミット履歴を参照するので、CodeBuildのdepthを規定値である1(=シャロークローン)からFullに変更している。

Gitのクローンの深さ(=depth)をFullに設定する。

なお、本稿でCodepPipelineを利用していないのは、CodepPipelineがチェックアウトするとCodeBuild環境にローカルリポジトリが作成されないためである。

##再実行について
S3バケットのファイルに何らかの不具合が生じた場合(誤ってS3のファイルを削除した等)は、CodeBuildを直接実行することで対応できる。buildspec.ymlでブランチ名から配信先バケットを判断しているので、Lambdaから呼び出されても、CodeBuildのコンソールから実行されても、問題なくファイル配信される。

以上。

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?