EC2 + CodePipeline(Code 3兄弟)で WebアプリをCI/CDデプロイする【完全 AWS CI/CD 体験】

AWS Basic
スポンサーリンク
スポンサーリンク

はじめに

「GitHub Actions は GitHub に依存してしまう。AWS だけで CI/CD を完結させたい」——そんなニーズに応えるのが AWS Code 4 兄弟(CodeCommit・CodeBuild・CodeDeploy・CodePipeline) です。さらに共通ライブラリは AWS CodeArtifact で管理するフルマネージドな AWS CI/CD パイプラインを構築します。

前のハンズオン(EC2 + GitHub Actions)との最大の違いは、すべてが AWS の中で完結することです。ソース管理・ビルド・ライブラリ管理・デプロイ、すべてを AWS サービスで担います。

[CodeCommit リポジトリ] ← git push
         ↓
[CodePipeline: my-cp-pipeline]
  Stage 1: Source  — CodeCommit からソースを取得
  Stage 2: Build   — CodeBuild で mvn package
                        ├─ CodeArtifact から認証トークン取得
                        ├─ common-lib を CodeArtifact に publish
                        ├─ CodeArtifact から common-lib を取得
                        └─ webapp.war を生成
  Stage 3: Deploy  — CodeDeploy で EC2 に配備
                        ├─ Tomcat を停止
                        ├─ WAR を配置
                        └─ Tomcat を再起動
         ↓
[EC2: Tomcat + Spring Boot]  my-cpapp
         ↓
[ALB: my-cp-alb] ← インターネット
         ↓
[RDS MySQL: my-cp-rds]

このハンズオンで体験できること:

  • CodeCommit + CodeBuild + CodeDeploy + CodePipeline による完全 AWS CI/CD
  • CodeArtifact による Maven ライブラリの社内管理(Maven Central のプロキシも体験)
  • buildspec.yml でビルド手順をコード化する
  • git-remote-codecommit で AWS CLI 認証のまま CodeCommit に push する
  • CloudFormation で全リソース(パイプラインを含む)を一括構築

コード詳細は GitHub を参照してください。


-->

スポンサーリンク

キーワード解説

用語意味
CodeCommitGit リポジトリを AWS 内でフルマネージドに管理するサービス。GitHub の AWS 版
CodeBuildbuildspec.yml でビルド手順をコード化し、マネージド環境でビルドを実行するサービス
CodeDeployEC2 への WAR 配置・サービス再起動・ヘルスチェックを自動化するサービス
CodePipelineSource → Build → Deploy のステージを自動で連結する CI/CD オーケストレーター
CodeArtifactMaven/npm/PyPI ライブラリを AWS 内で管理・共有するマネージドリポジトリ。Maven Central のプロキシとしても機能
buildspec.ymlCodeBuild が実行するビルドステップをコードで定義するファイル
appspec.ymlCodeDeploy がデプロイ時に実行するファイル配置とフックスクリプトを定義するファイル
git-remote-codecommitAWS CLI の認証情報を使って CodeCommit に push できるツール(Git 専用認証情報の設定不要)
SSM Parameter StoreDB パスワードなどの設定値を暗号化して管理し、EC2 から安全に取得できる AWS のサービス

スポンサーリンク

① 全体構成を理解する

CodeArtifact とは

CodeArtifact は AWS が提供するマネージドな Maven リポジトリです。GitHub Packages との大きな違いの一つが Maven Central のプロキシ機能です。

mvn package
  └─ CodeArtifact (my-cp-libs)
       ├── 社内ライブラリ: com.example:common-utils:1.0.0  ← CodeBuild が publish
       └── 外部ライブラリ: org.springframework.boot:*      ← Maven Central から透過的に取得

外部依存関係も CodeArtifact 経由でキャッシュされるため、インターネット接続なしでも再現性の高いビルドが可能になります。

buildspec.yml の処理フロー

buildspec.yml は CodeBuild が実行するビルド手順を定義します:

phases:
  install:
    runtime-versions:
      java: corretto17    # Amazon Corretto 17 を使用

  pre_build:
    commands:
      # settings.xml に書き込んで Maven 認証を設定
      - CODEARTIFACT_TOKEN=$(aws codeartifact get-authorization-token ...)
      - CODEARTIFACT_URL=$(aws codeartifact get-repository-endpoint ...)

  build:
    commands:
      # common-lib を CodeArtifact に publish(すでに存在する場合はスキップ)
      - mvn deploy -f common-lib/pom.xml -Dcodeartifact.url="$CODEARTIFACT_URL"
      # app の WAR をビルド(CodeArtifact から common-lib を取得)
      - mvn package -f app/pom.xml -DskipTests -Dcodeartifact.url="$CODEARTIFACT_URL"
      - cp app/target/webapp.war webapp.war

artifacts:
  files:
    - webapp.war
    - appspec.yml
    - scripts/**/*   # CodeDeploy のフックスクリプト

ポイント:pom.xml の CodeArtifact URL はプレースホルダー(${codeartifact.url})で、buildspec.yml が -Dcodeartifact.url= で実行時に渡します。pom.xml を事前に編集する必要はありません。


② CloudFormation スタックを作成する

自分の IP アドレスを確認し(curl https://checkip.amazonaws.com)、CloudFormation でインフラを一括作成します:

aws cloudformation deploy ^
  --template-file ec2-codepipeline/infra/template.yaml ^
  --stack-name my-cpapp-stack ^
  --parameter-overrides EmployeeId=my DBPassword=Handson1234! MyIP=123.456.78.901/32 ^
  --capabilities CAPABILITY_NAMED_IAM ^
  --region ap-northeast-1

所要時間:約 10〜15 分(VPC・EC2・RDS の作成に時間がかかります)

CloudFormation スタックが作成するリソース:

リソース名前
VPC / サブネット / IGWmy-cp-vpc
EC2(Amazon Linux 2023 + Tomcat 10.1)my-cpapp
ALBmy-cp-alb
RDS MySQL 8.0my-cp-rds
S3(パイプラインアーティファクト)my-cp-artifacts-{アカウントID}
CodeCommit リポジトリmy-cpapp
CodeArtifact ドメイン / リポジトリmy-domain / my-libs
CodeBuild プロジェクトmy-cpapp-build
CodePipelinemy-cp-pipeline
CodeDeploy Application + Deployment Groupmy-cpapp
SSM Parameter Store/my/cpapp/db-host, /my/cpapp/db-password
IAM ロール(EC2・CodeBuild・CodeDeploy・CodePipeline 用)


③ Outputs を確認する

aws cloudformation describe-stacks ^
  --stack-name my-cpapp-stack ^
  --query "Stacks[0].Outputs" ^
  --output table ^
  --region ap-northeast-1

CodeCommitCloneUrlHttpALBEndpoint の値を控えておきます。


④ git-remote-codecommit をインストールする

CodeCommit への push には git-remote-codecommit を使います。AWS CLI の認証情報をそのまま使えるため、Git 専用の認証情報を別途作成する必要がありません:

pip install git-remote-codecommit

インストール後、codecommit:: プレフィックスの URL で clone・push が可能になります。


⑤ ソースコードを CodeCommit に push する

⑤-1 CodeCommit リポジトリを clone する

git clone codecommit::ap-northeast-1://my-cpapp %TEMP%\my-cpapp

codecommit:: プレフィックスを使うことで、AWS CLI の認証情報が自動的に使われます(認証プロンプトは出ません)。

⑤-2 ソースコードをコピーして push する

xcopy ec2-codepipeline\* %TEMP%\my-cpapp\ /E /I /H /Y
cd %TEMP%\my-cpapp

git add .
git commit -m "initial commit"
git branch -M main
git push origin main

push が完了すると CodePipeline が自動的に起動します。


⑥ CodePipeline の動作を確認する

AWS コンソール → CodePipelinemy-cp-pipeline

3 つのステージが順番に実行されます:

ステージ処理内容目安時間
SourceCodeCommit からソース取得数秒
BuildCodeBuild が buildspec.yml を実行(common-lib publish → WAR ビルド)5〜8 分
DeployCodeDeploy が EC2 に配備(stop → install → start → validate)2〜3 分

合計:約 8〜10 分


⑦ CodeBuild のログを確認する

AWS コンソール → CodeBuildmy-cpapp-build → 「ビルド履歴」タブ

ビルド実行をクリックするとインラインログが確認できます。以下が表示されれば正常です:

=== CodeArtifact 認証トークン取得 ===
CodeArtifact URL = https://my-domain-XXXX.d.codeartifact.ap-northeast-1.amazonaws.com/maven/my-libs/
Maven settings.xml 生成完了
=== common-lib を CodeArtifact に publish ===
[INFO] BUILD SUCCESS
=== webapp WAR をビルド ===
[INFO] BUILD SUCCESS
=== デプロイパッケージを準備 ===
ビルド完了

CodeArtifact の認証トークンは 12 時間有効な一時トークンです。有効期限が切れても次のビルド時に自動取得されるため、管理の手間がありません。


⑧ CodeDeploy の状況を確認する

AWS コンソール → CodeDeploy → アプリケーション → my-cpapp → デプロイグループ → 最新のデプロイメント

各フックスクリプト(stop_server → install → start_server → validate_service)の実行結果が確認できます。デプロイが失敗した場合はここでエラー詳細を確認します。


⑨ アプリの動作確認をする

パイプラインが成功したら ALB 経由でアクセスします:

curl http://<ALBEndpoint の値>/api/health
rem → {"status":"ok","message":null,"data":"OK"}

curl http://<ALBEndpoint の値>/api/items
rem → {"status":"ok","message":null,"data":[]}

ブラウザで ALBEndpoint にアクセスするとアイテム管理 UI が表示されます。


⑩ CI/CD サイクルを体験する

CodeCommit にコードを push するだけでパイプラインが自動実行される CI/CD を体験します:

cd %TEMP%\my-cpapp

app\src\main\resources\templates\index.html を開いてタイトルを変更します:

<!-- 変更後 -->
<h1>Spring Boot + RDS Item Manager (EC2 v2) <span class="badge">CodePipeline</span></h1>
git add app\src\main\resources\templates\index.html
git commit -m "feat: update title to EC2 v2"
git push origin main

CodePipeline コンソール(my-cp-pipeline)で全ステージが成功になるまで待ちます(約 8〜10 分)。ALB にアクセスしてタイトルが変わっていることを確認します。


⑪ CodeArtifact のパッケージを確認する

AWS コンソール → CodeArtifact → ドメイン my-domain → リポジトリ my-libs → パッケージ一覧

com.example:common-utils:1.0.0 が登録されていることを確認します。CLI でも確認できます:

aws codeartifact list-packages ^
  --domain my-domain ^
  --domain-owner 123456789012 ^
  --repository my-libs ^
  --region ap-northeast-1

また、Maven Central のプロキシとして機能しているため、org.springframework.boot なども一覧に表示されます。これらは外部から初回取得時にキャッシュされたものです。


⑫ SSM Session Manager で EC2 に接続する(オプション)

キーペアなしで EC2 内部を確認できます:

aws ssm start-session ^
  --target i-xxxxxxxxxxxxxxxxx ^
  --region ap-northeast-1
# Tomcat のステータス確認
sudo systemctl status tomcat

# CodeDeploy エージェントのログ確認
sudo cat /var/log/aws/codedeploy-agent/codedeploy-agent.log

# SSM から取得した DB 接続情報の確認
sudo cat /opt/tomcat/current/bin/setenv.sh

# Tomcat ログの確認
sudo journalctl -u tomcat -n 50

⑬ リソースを削除する

CodeArtifact にパッケージが存在するとドメインが削除できないため、先にパッケージを手動削除します。

① CodeArtifact のパッケージを削除する

aws codeartifact delete-package-versions ^
  --domain my-domain ^
  --domain-owner 123456789012 ^
  --repository my-libs ^
  --format maven ^
  --namespace com.example ^
  --package common-utils ^
  --versions 1.0.0 ^
  --region ap-northeast-1

aws codeartifact delete-package ^
  --domain my-domain ^
  --domain-owner 123456789012 ^
  --repository my-libs ^
  --format maven ^
  --namespace com.example ^
  --package common-utils ^
  --region ap-northeast-1

② S3 バケットを空にする

aws cloudformation describe-stacks ^
  --stack-name my-cpapp-stack ^
  --query "Stacks[0].Outputs[?OutputKey=='ArtifactBucketName'].OutputValue" ^
  --output text ^
  --region ap-northeast-1

aws s3 rm s3://<ArtifactBucketName の値> --recursive

③ CloudFormation スタックを削除する

aws cloudformation delete-stack ^
  --stack-name my-cpapp-stack ^
  --region ap-northeast-1

aws cloudformation wait stack-delete-complete ^
  --stack-name my-cpapp-stack ^
  --region ap-northeast-1

echo 削除完了

④ ローカルの clone ディレクトリを削除する

rmdir /S /Q %TEMP%\my-cpapp

まとめ:学んだ概念

概念ポイント
CodeCommitGit リポジトリを AWS 内でフルマネージドに管理。git-remote-codecommit で AWS CLI 認証のまま push できる
CodeBuildbuildspec.yml でビルド手順をコード化。CodeArtifact の認証トークン取得→ publish → WAR ビルドまで自動化
CodeDeployEC2 への WAR 配置・サービス再起動・ヘルスチェックを自動化。appspec.yml でフックスクリプトを定義
CodePipelineSource → Build → Deploy のステージを自動で連結する CI/CD オーケストレーター
CodeArtifactMaven ライブラリを AWS 内で管理。Maven Central のプロキシとしても機能し、外部依存関係もキャッシュ
buildspec.ymlCodeBuild が実行するビルドステップをコードで定義するファイル
git-remote-codecommitAWS CLI 認証情報を使って CodeCommit に push できるツール(Git 専用認証情報不要)
SSM Parameter StoreDB パスワードをインスタンスに安全に渡す仕組み

GitHub Actions を使った前のハンズオンと比較すると、CodePipeline は すべてが AWS 内で完結する一方、GitHub Actions は Git リポジトリと AWS の柔軟な組み合わせが強みです。どちらを使うかはチームの方針や既存インフラに合わせて選択しましょう。

次のステップとして、CDK + ECS Fargate ハンズオンで EC2 からコンテナ化への移行も体験してみましょう。

コメント