AWSのEC2を使ってCodeCommitのソースを定期的にCICDしてみた②〜CICD設定編〜

過去記事でHUGOをAWS環境で自動デプロイするための手順を紹介しましたがEC2でデプロイする方法に切り替えたのでその内容を紹介します。

Ishiguro Suguru

前回の記事の続きです。

AWSのEC2を使ってCodeCommitのソースを定期的にCICDしてみた①〜EC2構築編〜

EC2のCICD処理の流れ

前回の記事で作成したEC2にスクリプトを配置して起動時にビルドとデプロイを行います。 EC2でビルド・デプロイをする流れは以下のとおりです。

  1. CloudWatchEventでインスタンス起動

  2. インスタンス起動でスクリプト実行

    1. CodeCommitからビルドするソースを取得
    2. 取得したソースのビルド
    3. S3にビルドしたファイルを転送
    4. CloudFrontのキャッシュをクリア
    5. ビルドしたファイルの削除
  3. CloudWatchEventでインスタンス停止

まずはEC2起動時のスクリプトと起動方法を説明します。

EC2インスタンス起動時のCICDスクリプト作成・配置

前提としてSSM(AWS Session Manager)を使って接続しています。

ユーザーはSSMのssm-userを使用しているため以下のサンプルコードの該当部分を適宜置き換えてください。

まずはsystemdを使ったスクリプト自動起動の設定を行います。

参考情報:systemd超入門

参考情報:Amazon Linux 2 が起動してネットワークが有効になった後で自作スクリプトを実行する方法を調べてみた

起動スクリプト設定

以下の起動設定を定義したsystemdのユニットファイルを作成します。

ExecStartExecStopで実行するスクリプトの指定、UserGroupで実行ユーザを指定します。 このパラメータは環境に応じて変更してください。

  • build-for-hugo.service
[Unit]
Description=exec by systemd
After=network-online.target

[Service]
Restart=no
Type=simple
ExecStart=/home/ssm-user/script/build-for-hugo/main.sh systemd start
ExecStop=/home/ssm-user/script/build-for-hugo/main.sh systemd stop
User=ssm-user
Group=ssm-user

[Install]
WantedBy=network-online.target

ファイル作成と設定は以下のコマンドを実行してください。

# vimを起動し上記ファイルの内容を貼り付け
sudo vim /etc/systemd/system/build-for-hugo.service
# 権限変更
sudo chmod 644 /etc/systemd/system/build-for-hugo.service
# 起動設定
sudo systemctl daemon-reload
sudo systemctl enable build-for-hugo
> Created symlink from /etc/systemd/system/network-online.target.wants/build-for-hugo.service to /etc/systemd/system/build-for-hugo.service.
# 結果確認
sudo systemctl list-unit-files | grep build-for-hugo
> build-for-hugo.service enabled

CICDスクリプトの作成

次にCICDを実行するスクリプトを作成します。

  • main.sh
#!/bin/bash

sudo logrotate -f /etc/logrotate.conf

readonly SCRIPT_DIR="/home/ssm-user/script/build-for-hugo"
readonly LOGFILE="${SCRIPT_DIR}/log/script.log"
readonly BUCKET_NAME="bucket_name"
readonly DISTRIBUTION_ID="dist_id"
readonly DOCKER_IMAGE="peaceiris/hugo:v0.74.3-mod"

readonly PROCNAME=${0##*/}
function log() {
  local fname=${BASH_SOURCE[1]##*/}
  echo -e "$(date '+%Y-%m-%dT%H:%M:%S') ${PROCNAME} (${fname}:${BASH_LINENO[0]}:${FUNCNAME[1]}) $@" | tee -a ${LOGFILE}
}

case "$2" in
start)
  log "==========$1:script start=========="
  log "git clone"
  git clone ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/xxxxxx ${SCRIPT_DIR}/src >> ${LOGFILE} 2>&1
  log "build"
  sudo docker run --rm -v ${SCRIPT_DIR}/src:/src ${DOCKER_IMAGE} --gc --minify --cleanDestinationDir >> ${LOGFILE} 2>&1
  log "s3 sync"
  aws s3 sync --delete ${SCRIPT_DIR}/src/public/ s3://${BUCKET_NAME} >> ${LOGFILE} 2>&1
  log "cloudfront create invalidation"
  aws cloudfront create-invalidation --distribution-id ${DISTRIBUTION_ID} --paths "/*" >> ${LOGFILE} 2>&1
  sudo rm -rf ${SCRIPT_DIR}/src
  log "==========$1:script end=========="
  ;;
stop)
  ;;
esac

exit

ファイル作成と設定は以下のコマンドを実行してください。

HUGOのビルドは以下のサイトにあるDockerイメージを使っています。 HUGOのバージョンごとにイメージが用意されているためご自身の利用環境に合わせてイメージを取得してください。

https://github.com/peaceiris/hugo-extended-docker

# スクリプト配置先とログ保存先のディレクトリ作成
mkdir ~/script
mkdir ~/script/build-for-hugo
mkdir ~/script/build-for-hugo/log
# vimを起動し上記ファイルの内容を貼り付け
vim ~/script/build-for-hugo/main.sh
# 権限変更
sudo chmod 755 ~/script/build-for-hugo/main.sh

# HUGOをビルドするためのDockerイメージ取得
sudo docker pull peaceiris/hugo:v0.74.3-mod

# logrotate設定(設定例は以下参照)
sudo vim /etc/logrotate.d/build-for-hugo

参考までにlogrotateは以下のように設定しています。

/home/ssm-user/script/build-for-hugo/log/script.log {
    missingok
    notifempty
    rotate 30
    daily
    compress
}

AWSリソースへのアクセス設定

実行するスクリプトの中でAWSリソースへアクセスする箇所があるため忘れずにアクセス設定をしておきましょう。 アクセス設定が必要な箇所は以下になります。

  • CodeCommit接続
  • S3, CloudFront接続(AWS CLI)

CodeCommit接続設定はスクリプト内のgit clone ssh:~で必要になります。 今回はsshで接続していますがhttpsでも問題ないため適宜設定してください。

参考情報:Linux, macOS, or Unix で AWS CodeCommit リポジトリへの SSH 接続をセットアップする手順

またAWS CLIを使ってS3へのファイル転送aws s3 sync ~とCloudFrontのキャッシュ削除aws cloudfront ~を行っています。 このコマンドが実行できるようにIAMでアクセスキーを取得してaws configureで認証情報を設定しておきましょう。

CloudWatchを使ったEC2の自動起動・停止の設定

最後にEC2の自動起動と自動停止のジョブをCloudWatchを使って作成します。

この設定は非常に簡単で以下のサイトで詳細に説明いただいてますので参考にしてみてください。

[AWS] CloudWatchでEC2の自動起動・停止をスケジュールする

最後に

今回はEC2を使ってCICDを実現しました。

Dockerを使ってビルド環境を作成すればHUGO以外のビルドを行いたいときなどサクッと環境を作れるためオススメです!

また本当はCloudWatchを使ったEC2の自動起動&停止はEC2のタグを使ってSystem Managerからやりたかったのですが上手くいきませんでした…

解決できればどこか別の機会で紹介したいと思います!

comments powered by Disqus