AWS CodePipeline + CodeBuild CI/CD ハンズオン

GitHub の変更を検知して ECS Fargate に自動デプロイするパイプラインを構築する

CodePipeline CodeBuild Amazon ECR ECS Fargate マネコン操作 中〜上級 所要時間 90〜120 分 v1.0

📋 概要

このハンズオンでは GitHub へのコードプッシュをトリガーに、AWS CodePipeline が自動的に Docker イメージをビルドして Amazon ECR に保存し、ECS Fargate サービスに新バージョンをデプロイするパイプラインを構築します。

項目内容
対象サービスCodePipeline、CodeBuild、ECR、ECS Fargate
主な学習内容パイプライン構築・buildspec.yml 記述・ECS ローリングデプロイ自動化
所要時間90〜120 分
難易度★★★★☆(中〜上級者向け)
前提知識Docker・ECS Fargate の基礎(ECS ハンズオン修了推奨)
費用目安約 1〜3 USD(CodeBuild ビルド時間・ECS 稼働時間による)
ℹ️ CodeCommit は 2024年7月に廃止

AWS は CodeCommit の新規利用を 2024年7月25日に停止しました。このハンズオンでは GitHub を Source として CodePipeline と連携します(AWS CodeStar Connections を使用)。

🏗️ アーキテクチャ

🐙 GitHub リポジトリ
main ブランチへの push をトリガー
↓ Webhook(CodeStar Connections)
🚀 AWS CodePipeline
Stage 1: Source → Stage 2: Build → Stage 3: Deploy
↓ ソースコード取得
🔨 AWS CodeBuild
Docker build → ECR push → imagedefinitions.json 生成
↓ imagedefinitions.json
📦 Amazon ECR
Docker イメージ保管(タグ: commit SHA)
↓ タスク定義更新 → ローリングデプロイ
⚡ ECS Fargate サービス
新タスク起動 → ヘルスチェック → 旧タスク停止

作成するリソース

リソース名前備考
ECR リポジトリhandson-appDocker イメージ保管
CodeStar Connectionshandson-github-connectionGitHub 認証
CodeBuild プロジェクトhandson-buildイメージビルド・プッシュ
IAM ロール(CodeBuild)codebuild-handson-roleECR/CWL 権限
IAM ロール(CodePipeline)codepipeline-handson-roleS3/CodeBuild/ECS 操作権限
S3 バケット(アーティファクト)codepipeline-artifacts-<id>パイプライン内部で自動作成
CodePipelinehandson-pipeline3 ステージ構成

✅ 前提条件

⚠️ ECS クラスター・サービスを事前に用意

このハンズオンは既存の ECS Fargate サービスへのデプロイを前提としています。ECS ハンズオン未実施の場合は先に実施するか、以下の最小構成を用意してください。

  • ECS クラスター名: handson-ecs-cluster
  • ECS サービス名: handson-ecs-service
  • タスク定義のコンテナ名: handson-app

📁 ステップ 1 ― GitHub リポジトリとサンプルアプリの準備

CI/CD パイプラインのソースとなる GitHub リポジトリを用意します。

1-1. GitHub リポジトリを作成

GitHub で新規リポジトリ handson-appPublic または Private で作成します。

1-2. サンプルアプリファイルを作成

以下の 3 ファイルをリポジトリに追加します。

app.js(Node.js の簡単な HTTP サーバー)

const http = require('http');
const PORT = process.env.PORT || 3000;
const VERSION = process.env.APP_VERSION || 'v1.0';

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end(`Hello from ECS Fargate! Version: ${VERSION}\n`);
});

server.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

Dockerfile

FROM node:20-alpine
WORKDIR /app
COPY app.js .
EXPOSE 3000
CMD ["node", "app.js"]

buildspec.yml(CodeBuild のビルド定義)

version: 0.2

env:
  variables:
    AWS_DEFAULT_REGION: ap-northeast-1
    IMAGE_REPO_NAME: handson-app
  parameter-store:
    AWS_ACCOUNT_ID: /handson/aws-account-id

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - ECR_URI=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${IMAGE_REPO_NAME}
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ECR_URI
      - IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - echo Image tag is $IMAGE_TAG
  build:
    commands:
      - echo Building Docker image...
      - docker build -t $ECR_URI:$IMAGE_TAG .
      - docker tag $ECR_URI:$IMAGE_TAG $ECR_URI:latest
  post_build:
    commands:
      - echo Pushing Docker image...
      - docker push $ECR_URI:$IMAGE_TAG
      - docker push $ECR_URI:latest
      - echo Writing imagedefinitions.json...
      - printf '[{"name":"handson-app","imageUri":"%s"}]' $ECR_URI:$IMAGE_TAG > imagedefinitions.json

artifacts:
  files: imagedefinitions.json
ℹ️ imagedefinitions.json とは

CodePipeline の ECS デプロイステージが読み込む JSON ファイルです。name はタスク定義内のコンテナ名(ECS ハンズオンでは handson-app)と完全に一致させる必要があります。一致しないとデプロイステージでコンテナが見つからず失敗します。このファイルにより ECS がどのイメージをデプロイするかを判断します。

1-3. SSM パラメーターストアに AWS アカウント ID を登録

buildspec.yml から参照するアカウント ID を SSM に保存します。

aws ssm put-parameter \ --name /handson/aws-account-id \ --value "$(aws sts get-caller-identity --query Account --output text)" \ --type String \ --region ap-northeast-1
✅ 確認ポイント

GitHub リポジトリに app.jsDockerfilebuildspec.yml の 3 ファイルが存在すれば準備完了です。

📦 ステップ 2 ― Amazon ECR リポジトリの作成

CodeBuild がビルドした Docker イメージを保管する ECR リポジトリを作成します。

2-1. ECR コンソールを開く

AWS マネジメントコンソールで 「Elastic Container Registry」 を検索して開きます。「リポジトリを作成」 をクリックします。

2-2. リポジトリを設定
可視性設定プライベート
リポジトリ名handson-app
タグのイミュータビリティ無効(デフォルト)

「リポジトリを作成」をクリックします。

2-3. ライフサイクルポリシーを設定(推奨)

古いイメージが蓄積しないよう、最新 10 件のみ保持するポリシーを設定します。

リポジトリを開き 「ライフサイクルポリシー」→「ルールを作成」 をクリックします。

ルールの優先度1
イメージのステータス任意
一致条件イメージの個数:10 より多い
アクション期限切れにする
✅ 確認ポイント

ECR リポジトリ一覧に handson-app が表示されれば成功です。URI(<account-id>.dkr.ecr.ap-northeast-1.amazonaws.com/handson-app)をメモしておきます。

🔗 ステップ 3 ― GitHub 接続(CodeStar Connections)

CodePipeline が GitHub リポジトリを監視できるよう、AWS と GitHub を接続します。

3-1. CodePipeline コンソールから接続を作成

AWS マネジメントコンソールで 「CodePipeline」 を検索して開きます。左メニューの 「設定」→「接続」→「接続を作成」 をクリックします。

プロバイダーGitHub
接続名handson-github-connection

「GitHub に接続」をクリックします。

3-2. GitHub の OAuth 認証を完了

GitHub の認証ページにリダイレクトされます。「AWS Connector for GitHub」 アプリのインストールを許可します。

1
「新しいアプリをインストール」をクリック
2
対象リポジトリ(handson-app)を選択して「Install」
3
「接続」をクリックして AWS コンソールに戻る
✅ 確認ポイント

接続一覧でステータスが 「利用可能」 になれば成功です。「保留中」のままの場合は「保留中の接続を更新」をクリックしてください。

🔨 ステップ 4 ― CodeBuild プロジェクトの作成

Docker ビルドと ECR プッシュを行う CodeBuild プロジェクトを作成します。

4-1. CodeBuild コンソールを開く

「CodeBuild」 を検索して開きます。「ビルドプロジェクトを作成する」 をクリックします。

4-2. プロジェクトの基本設定
プロジェクト名handson-build
4-3. ソースの設定
ソースプロバイダーGitHub
リポジトリGitHub アカウントのリポジトリ → handson-app
ブランチmain
4-4. 環境の設定
設定項目設定値
環境イメージマネージド型イメージ
コンピューティングEC2
オペレーティングシステムAmazon Linux
ランタイムStandard
イメージaws/codebuild/standard:7.0(最新)
特権モード✅ 有効(Docker ビルドに必須)
サービスロール新しいサービスロール → codebuild-handson-role
⚠️ 特権モードは必須

Docker デーモンを使用するため「特権モードを有効にする」にチェックを入れてください。これなしでは docker build が失敗します。

4-5. ビルド仕様の設定
ビルド仕様リポジトリのビルド仕様ファイルを使用(buildspec.yml)
4-6. IAM ロールに権限を追加

プロジェクト作成後、自動作成された IAM ロール codebuild-handson-role に以下のポリシーを追加します。

IAM コンソール → ロール → codebuild-handson-role → 「許可を追加」→「ポリシーをアタッチ」

  • AmazonEC2ContainerRegistryPowerUser — ECR への push 権限
  • AmazonSSMReadOnlyAccess — SSM パラメーター読み取り権限
✅ 動作確認:手動でビルドを実行

CodeBuild コンソールで handson-build を選択 →「ビルドを開始」をクリックします。ビルドログを確認し「成功」になれば ECR にイメージが push されています。

🚀 ステップ 5 ― CodePipeline パイプラインの作成

Source・Build・Deploy の 3 ステージで構成されるパイプラインを作成します。

5-1. パイプラインの作成を開始

CodePipeline コンソールで 「パイプラインを作成する」 をクリックします。

パイプライン名handson-pipeline
パイプラインタイプV2(推奨)
実行モードキュー
サービスロール新しいサービスロール(自動作成)

「次へ」をクリックします。

5-2. Source ステージの設定
ソースプロバイダーGitHub(バージョン 2)
接続handson-github-connection
リポジトリ名(自分の GitHub ユーザー名)/handson-app
デフォルトブランチmain
出力アーティファクト形式CodePipeline のデフォルト

「次へ」をクリックします。

5-3. Build ステージの設定
ビルドプロバイダーAWS CodeBuild
リージョンアジアパシフィック(東京)
プロジェクト名handson-build

「次へ」をクリックします。

5-4. Deploy ステージの設定
デプロイプロバイダーAmazon ECS
リージョンアジアパシフィック(東京)
クラスター名handson-ecs-cluster
サービス名handson-ecs-service
イメージ定義ファイルimagedefinitions.json

「次へ」→「パイプラインを作成する」をクリックします。

ℹ️ Amazon ECS vs CodeDeploy(Blue/Green)

「Amazon ECS」プロバイダーはローリングアップデートです。ダウンタイムゼロの Blue/Green デプロイが必要な場合は「CodeDeploy」プロバイダーを選択し、appspec.yml の設定が別途必要になります。

✅ 確認ポイント

パイプライン作成後、自動的に最初の実行が始まります。Source → Build → Deploy の各ステージが順に「成功」になれば構築完了です(初回は 5〜10 分かかります)。

✅ ステップ 6 ― 動作確認(git push → 自動デプロイ)

コードを変更して git push し、パイプラインが自動起動してデプロイされることを確認します。

6-1. アプリのバージョンを変更してプッシュ

app.jsVERSION を変更します。

const VERSION = process.env.APP_VERSION || 'v2.0';  // v1.0 → v2.0 に変更
git add app.js git commit -m "feat: update version to v2.0" git push origin main
6-2. パイプラインの実行を確認

CodePipeline コンソールで handson-pipeline を開きます。数秒〜数十秒でパイプラインが自動起動し、各ステージが順に実行されます。

ステージ確認ポイント所要時間目安
SourceGitHub から最新コミットを取得〜30 秒
BuildDocker ビルド・ECR プッシュ2〜5 分
DeployECS サービスの新タスク起動1〜3 分
6-3. ECS サービスで新タスクを確認

ECS コンソール → クラスター → handson-ecs-cluster → サービス → handson-ecs-service → タスクタブを確認します。新しいタスクが起動し旧タスクが停止すれば成功です。

6-4. ブラウザでアプリの更新を確認

ALB の DNS 名またはサービスのパブリック IP にアクセスして Version: v2.0 が表示されれば CI/CD パイプライン完成です。

🎉 CI/CD パイプライン完成!

今後は main ブランチへの push だけで自動的にビルド・デプロイが行われます。

🧹 クリーンアップ

⚠️ 課金防止のためクリーンアップを必ず実施してください

ECS Fargate・CodeBuild・CodePipeline(パイプライン実行数)・ECR(イメージ保管)などで課金が発生します。

削除手順(逆順で実施)

  1. ECS サービスを停止・削除(ECS ハンズオンで作成した場合)
  2. CodePipeline を削除
    CodePipeline → handson-pipeline →「削除」
  3. CodeBuild プロジェクトを削除
    CodeBuild → handson-build →「削除」
  4. CodeStar Connections の接続を削除
    CodePipeline → 設定 → 接続 → handson-github-connection →「削除」
  5. ECR リポジトリを削除
    ECR → handson-app →「削除」
  6. S3 アーティファクトバケットを削除
    S3 → codepipeline-* バケット →「空にする」→「削除」
  7. IAM ロールを削除
    codebuild-handson-roleAWSCodePipelineServiceRole-* を削除
  8. SSM パラメーターを削除
    SSM → パラメーターストア → /handson/aws-account-id →「削除」

学習のまとめ

習得したスキル実践内容
CI/CD パイプライン設計Source → Build → Deploy の 3 ステージ構成
buildspec.ymlDocker ビルド・ECR プッシュ・imagedefinitions.json 生成
GitHub 連携CodeStar Connections による OAuth 接続
ECS 自動デプロイimagedefinitions.json を使ったローリングアップデート
ECR ライフサイクル古いイメージの自動削除ポリシー