初心者がECSのCI/CDハンズオンやってみた

サムネイル

こんにちは!株式会社アイスリーデザイン エンジニアリング部の中島です。

前回は『初心者がCloud9を使わないECSハンズオンやってみた』という内容で、以下のECSのWebアプリケーションをデプロイするハンズオンに取り組みました。

ECS Web Application ハンズオン

今回はその発展編として、ECSのCI/CDに挑戦してみたいと思います。

まだ前回の記事をご覧になっていない方は、ぜひそちらを先に読んでから本記事を読み進めることをおすすめします。

CI/CDハンズオン

ハンズオン内では2種類の方法が紹介されています。

  1. GitHubを使用する方法
  2. AWS CodeCommitを使用する方法

調べたところ、AWS CodeCommitは2024年7月25日時点で新規利用受け付けを終了していました。

そのため、本記事ではGItHubを使用する方法で進めていきます。

今回のハンズオンのシステム構成図

1. GitHubリポジトリとビルド設定ファイルの作成

まずはこちらのURLからGitHubリポジトリを作成します。

rails-appという名前のリポジトリが作成されればOKです。

GitHubリポジトリ作成画面

続いて、開発環境からGItHubリポジトリにアクセスできるように、アクセストークンを作成します。

こちらのURLを開き、以下の設定でアクセストークンを作成しましょう。

アクセストークンの設定値

作成が完了したらアクセストークンをコピーして、GitHubリポジトリにアクセスするために以下のコマンドを実行します。

export USERNAME=<GitHubアカウントのユーザー名>

export ACCESS_TOKEN=<生成したアクセストークン>

export REPOSITORY_NAME=rails-app

次に以下のコマンドを実行して、作成したリポジトリをローカルのディレクトリと連携します。
`/workshop`は自分のディレクトリ名に差し替えてください。

cd /workshop

git init -b main

git remote add origin https://$USERNAME:$ACCESS_TOKEN@github.com/$USERNAME/$REPOSITORY_NAME.git

続いて、`/workshop`配下にビルド設定ファイルとなる`buildspec.yaml`を作成します。

中身は以下の通りです。

詳細については、こちらの「CodeBuild のビルド仕様に関するリファレンス」のドキュメントを参照してください。

version: 0.2

env:

 variables:

   CONTAINER_NAME: "rails-app"

phases:

 pre_build:

   commands:

     # AWS アカウント ID を取得する

     - AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)

     # リポジトリの URI を設定する

     - REPOSITORY_URI=${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/${CONTAINER_NAME}

     # コミット ID をもとに、コンテナイメージのタグを生成する

     - IMAGE_TAG=$(echo ${CODEBUILD_RESOLVED_SOURCE_VERSION} | cut -c 1-7)

     # ECR にログインする

     - aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com

 build:

   commands:

     # コンテナイメージをビルドする

     - docker build -t ${REPOSITORY_URI}:latest .

     # 生成したイメージタグを付与する

     - docker tag ${REPOSITORY_URI}:latest ${REPOSITORY_URI}:${IMAGE_TAG}

 post_build:

   commands:

     # ビルドしたコンテナイメージを ECR にプッシュする

     - docker push ${REPOSITORY_URI}:${IMAGE_TAG}

     # "コンテナの名前" と "コンテナイメージの URI" を imagedefinitions.json に書き込む

     - printf '[{"name":"%s","imageUri":"%s"}]' ${CONTAINER_NAME} ${REPOSITORY_URI}:${IMAGE_TAG}  > imagedefinitions.json

artifacts:

 files:

   - imagedefinitions.json

作成したらGitHubリポジトリにpushしましょう。

git add .

git commit -m "Initial commit"

git push origin main

2. パイプラインの作成

AWS CodePipelineを使用して、CI/CDパイプラインを作成していきます。

「カスタムパイプラインを構築する」を選択し、パイプライン名を入力したら次へ進みます。

パイプラインのソースプロバイダーには「GitHub(GitHubアプリ経由)」を選択し、「GitHubに接続する」をクリックします。

ソースステージの追加画面①

GitHub接続設定が完了したらパイプラインの設定画面に戻るので、以下の項目を入力して次へ進みます。

ソースステージの追加画面②

続いて、ビルドステージの設定を入力します。

ビルドステージの追加画面

「プロジェクトを作成する」を選択して、ビルドプロジェクトの設定でプロジェクト名とbuildspecファイル名を入力します。

buildspecファイル名の入力画面

CodePipelineに進むとテストステージの設定画面になりますが、今回はテストを行わないのでスキップします。

最後にデプロイステージを入力します。

デプロイステージの追加画面

以上でパイプラインの作成完了です!

しばらくするとBuildステージが失敗しますが、これはCodeBuildがECRリポジトリにアクセスする権限を持っていないことが原因のため、CodeBuildに指定したサービスロールに権限を追加しましょう。

IAMコンソールの「ロール」からCodeBuildに付与したロールを選択し、「許可を追加」「ポリシーをアタッチ」から、”AmazonEC2ContainerRegistryPowerUser” を選択して許可を追加します。

これでパイプラインの実行準備完了です!

3. パイプラインの実行

アプリケーションを修正し、パイプラインを実行します。

まずはDockerfileを開き、ハイライトされた箇所を追加します。

# ruby:3.2.1 というベースイメージを取得する

FROM public.ecr.aws/docker/library/ruby:3.2.1

# 必要なパッケージ群を取得する

RUN apt-get update -qq && \

   apt-get install -y nodejs postgresql-client npm && \

   rm -rf /var/lib/apt/lists/\*

# ローカルにあるファイルをコンテナイメージ内にコピーする

WORKDIR /myapp

COPY Gemfile /myapp/Gemfile

# Rails アプリケーションを作成する

RUN bundle install && \

   rails new . -O && \

   sed -i -e "52a\ config.hosts.clear\n  config.web_console.allowed_ips = '0.0.0.0/0'\n  config.action_dispatch.default_headers.delete('X-Frame-Options')" config/environments/development.rb

+ # welcome ページの背景色を blue にする

+ RUN sed -i -e "s/background-color: #F0E7E9;/background-color: #99CCFF;/g" /usr/local/bundle/gems/railties-7.2.2/lib/rails/templates/rails/welcome/index.html.erb

# Rails を 3000 番ポートで起動する

EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0", "-p", "3000"]

変更したDockerfileをGitHubにpushすると、パイプラインが起動されます。

デプロイの完了をCodePipelineで、新しいタスクの起動をECSタスクタブで確認したら、実際にアクセスしてみましょう。

Dockerfileを変更した通り背景色が切り替わっていることから、デプロイが完了したことが確認できました!

以上で、デプロイメントを自動化するCI/CDハンズオン終了です!

※リソースの削除はお忘れなく!

デプロイ完了を示す画面

おまけ

本記事では実施しませんが、公式ハンズオンではパイプライン実行後に以下の課題が用意されているので、興味がある方はぜひ挑戦してみてください!

Blue/Greenデプロイメントについてはこちらの記事で紹介されていますので、ぜひご一読ください。

Amazon ECSでNext.jsをブルーグリーンデプロイしてみる

最後に

前回の記事「初心者がCloud9を使わないECSハンズオンやってみた」とあわせて、ECSの作成からデプロイまで行えるようになりました!

これは資格勉強など、本や記事を読むだけでは得られない実践的な学びであり、理解を深めるうえで非常に有意義な経験だったと感じています。

今後も引き続き、「勉強から実践へ」という気持ちを大事にして、知識をしっかり自分のものにしていきたいと思います。

皆様もぜひ実践してみてください!