CDK Pipelines でインフラの CI/CD を構築する【git push だけで ALB + EC2 + RDS が自動デプロイ】

AWS Basic
スポンサーリンク
スポンサーリンク
  1. はじめに
  2. キーワード解説
  3. cdk-custom-constructs との比較
  4. ファイル構成と役割
  5. 使用するAWSサービス
  6. 前提条件
  7. 作業順序
  8. 【重要】⓪ 自分のIPアドレスを確認する
  9. ① キーペアの作成
  10. ② プロジェクトのセットアップ
  11. ③ GitHub との接続を作成する(CodeConnections)
    1. 接続を作成する
    2. GitHub App をインストールする
    3. 接続 ARN を確認する
  12. ④ cdk.json の設定
  13. ⑤ コードを GitHub にプッシュする
  14. ⑥ パイプラインスタックのデプロイ(初回のみ)
  15. ⑦ パイプラインの実行状況を確認する
    1. CloudFormation スタックの命名規則
    2. CloudFormation Outputs の確認
  16. ⑧ 動作確認
    1. 8-1. ALB 経由でWebアクセス確認
    2. 8-2. EC2 に SSH 接続する
    3. 8-3. EC2 から RDS への接続確認
    4. 8-4. SSH 接続を切断する
  17. ⑨ CI/CD を体験する(インフラ変更を push で自動反映)
    1. EC2 にタグを追加して CI/CD を確認する
    2. push する
    3. パイプラインの自動起動を確認する
    4. タグが反映されたことを確認する
  18. ⑩ リソース削除
    1. 1. パイプラインで作成されたスタックを削除する
    2. 2. パイプラインスタック自体を削除する
    3. 3. アーティファクト S3 バケットを削除する(必要な場合)
    4. 4. 仮想環境の終了
    5. 5. キーペアの削除(手動)
    6. 6. GitHub との接続を削除する(手動)
    7. 削除されるリソース一覧
  19. CDK Pipelines のポイント解説
    1. なぜ cdk deploy は初回だけ必要なのか
    2. Stage クラスの役割
    3. モノレポでの primary_output_directory
  20. トラブルシューティング
  21. まとめ

はじめに

「インフラの変更を反映するたびに cdk deploy を手動実行するのが面倒」「コードをプッシュするだけで AWS リソースが自動更新されるようにしたい」——これを実現するのが CDK Pipelines です。

この記事では、CDK カスタム Construct ハンズオンで構築した ALB + EC2(Tomcat) + RDS の3層構成を、CDK Pipelines(CodePipeline + CodeBuild) で CI/CD 化します。GitHub にコードをプッシュするだけで自動的にインフラがデプロイ・更新される仕組みを体験します。

GitHub リポジトリ
  ↓ push(自動トリガー)
CodePipeline (my-cdk3-pipeline)
  ├── Source:  GitHub (CodeConnections 経由)
  ├── Build:   CodeBuild — cdk synth
  ├── Mutate:  パイプライン自身を自動更新(セルフミューテーション)
  └── Deploy:  CloudFormation — ThreeTierStack
                  ↓
         [ALB: my-cdk3-alb]
                  ↓
         [EC2: my-cdk3-ap-instance]  ← Tomcat
                  ↓
         [RDS: my-cdk3-rds-mysql]    ← MySQL 8.0

このハンズオンで体験できること(インフラの CI/CD):

  • git push するだけで VPC / EC2 / RDS / ALB などのインフラ構築・更新が自動実行される
  • SG ルール追加・インスタンスタイプ変更などのインフラ変更が push で自動反映される
  • パイプライン自体の定義変更も自動反映される(セルフミューテーション

このハンズオンで体験できないこと(アプリの CI/CD):

このハンズオンでは HTML を EC2 の UserData に埋め込んでいます。UserData は EC2 の初回起動時にのみ実行される仕組みのため、push しても既存 EC2 上のファイルは書き換えられません。
Java アプリ(WAR ファイル)を push で自動デプロイしたい場合は、次のハンズオン cdk-webapp-pipeline(CodeDeploy を使用)で体験します。


この記事は CDK カスタム Construct ハンズオン(cdk-custom-constructs) の発展記事です。
CDK の基本(Bootstrap・synth・deploy)と カスタム Construct を体験済みの方向けです。コード詳細は GitHub を参照してください。


-->

スポンサーリンク

キーワード解説

用語意味
CDK PipelinesCDK アプリの CI/CD を定義する高レベル Construct ライブラリ。内部で CodePipeline + CodeBuild + CloudFormation を組み合わせる
Stageパイプラインのデプロイ単位。複数スタックをひとまとめにしてパイプラインに追加できる
セルフミューテーションパイプライン自身のコード(pipeline_stack.py)を変更して push するだけで、パイプラインが自動的に自分自身を更新する仕組み
CodeConnectionsGitHub などの外部 SCM と AWS を接続するサービス(旧 CodeStar Connections)。ブラウザからの GitHub App 認証が必要
Synth StepCodeBuild で cdk synth を実行し Cloud Assembly(CloudFormation テンプレート一式)を生成するパイプラインのステップ
セルフミューテーション後のデプロイMutate ステージでパイプラインが更新された後、続けて Deploy ステージが実行される

スポンサーリンク

cdk-custom-constructs との比較

比較項目cdk-custom-constructscdk-pipelines
デプロイ方法cdk deploy(手動)GitHub push → 自動
インフラ変更の反映毎回 cdk deploy を手動実行push するだけで自動反映
パイプライン管理なしCodePipeline がデプロイを管理
セルフミューテーションなしパイプライン自体もコードで管理・自動更新
初回デプロイcdk deploycdk deploy以降は push のみ
アプリデプロイEC2 起動時(UserData)EC2 起動時(UserData)※今回は同じ

インフラの構成は cdk-custom-constructs と完全に同等です。変わるのはデプロイの仕組み(手動 → 自動)です。


ファイル構成と役割

cdk-pipelines/
├── app.py                    ← CDK アプリ エントリポイント(PipelineStack を生成)
├── cdk.json                  ← CDK 設定・Context 変数(GitHub 接続情報を含む)
├── pipeline/
│   └── pipeline_stack.py     ← CodePipeline + Synth + Stage を定義するスタック
├── stages/
│   └── three_tier_stage.py   ← Stage(ThreeTierStack をデプロイ対象としてまとめる)
├── stacks/
│   └── three_tier_stack.py   ← 3層Web構成スタック(cdk-custom-constructs から流用)
└── components/
    └── three_tier_web.py     ← カスタム L3 Construct(cdk-custom-constructs から流用)
ファイル役割
pipeline_stack.pyパイプライン本体。Source・Synth Step・Stage を定義する
three_tier_stage.pyStage。ThreeTierStack を内包し、デプロイ対象としてパイプラインに渡す
three_tier_stack.py3層Web構成スタック(cdk-custom-constructs と同じ構造)
three_tier_web.pyカスタム Construct。cdk-custom-constructs から流用

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


使用するAWSサービス

サービス役割料金
VPCカスタムネットワーク空間無料
EC2(t2.micro)APサーバ(Tomcat)月750時間まで無料枠あり
RDS MySQL(db.t3.micro)マネージドDBサーバ月750時間まで無料枠あり
ALBロードバランサー約$0.008/時間 + LCU料金(無料枠なし
CodePipelineCI/CD パイプライン管理月1パイプラインまで無料枠あり
CodeBuildcdk synth を実行するビルド環境月100分まで無料枠あり
SSM Parameter StoreDBパスワードの安全な保管スタンダード層は無料
S3パイプラインのアーティファクト置き場無料枠あり
IAM各サービスの権限無料

注意: ALBは無料枠がありません。ハンズオン後は必ずリソースを削除してください。


前提条件

ツール確認コマンド
AWS CLI v2aws --version
Python 3.9 以上python --version
Node.js 18 以上node --version
CDK CLIcdk --version
Gitgit --version

AWS 認証確認:

aws sts get-caller-identity

CDK Bootstrap 確認(CDKToolkit スタックが存在すれば実施済み):

aws cloudformation describe-stacks ^
  --stack-name CDKToolkit ^
  --query "Stacks[0].StackStatus" ^
  --output text ^
  --region ap-northeast-1

GitHub アカウントが必要ですaws-learning-projects リポジトリに push できる状態にしておいてください。


作業順序

⓪ 自分のIPアドレスを確認する
      ↓
① キーペアを作成する(AWS CLI で実施)
      ↓
② プロジェクトのセットアップ(Python 仮想環境)
      ↓
③ GitHub との接続を作成する(CodeConnections)
      ↓
④ cdk.json を設定する
      ↓
⑤ コードを GitHub にプッシュする
      ↓
⑥ パイプラインスタックをデプロイする(初回のみ手動)
      ↓
⑦ パイプラインの実行状況を確認する
      ↓
⑧ 動作確認(ALBアクセス・SSH・RDS接続)
      ↓
⑨ CI/CD を体験する(インフラ変更を push で自動反映)
      ↓
⑩ リソース削除

【重要】⓪ 自分のIPアドレスを確認する

curl https://checkip.amazonaws.com

控えておく情報: 自分のIPアドレス(例: 203.0.113.1


① キーペアの作成

aws ec2 create-key-pair ^
  --key-name my-cdk3-key ^
  --query KeyMaterial ^
  --output text ^
  --region ap-northeast-1 > %USERPROFILE%\.ssh\my-cdk3-key.pem

%USERPROFILE%\.ssh\ が存在しない場合は先に mkdir %USERPROFILE%\.ssh を実行してください。


② プロジェクトのセットアップ

cd C:\my-aws\aws-learning-projects\cdk-pipelines

python -m venv .venv

.venv\Scripts\activate

pip install -r requirements.txt

プロンプトの先頭に (.venv) が表示されれば仮想環境が有効になっています。

重要: CDK コマンド(synth / deploy / destroy)はすべてこの仮想環境が有効な状態で実行する必要があります。
ターミナルを開き直した際は必ず最初に以下を実行してください。

cd C:\my-aws\aws-learning-projects\cdk-pipelines
.venv\Scripts\activate

③ GitHub との接続を作成する(CodeConnections)

CodePipeline が GitHub リポジトリを監視するために、GitHub との接続(CodeConnections) を作成します。接続の管理はブラウザから行います。

重要: AWS コンソールと GitHub の操作は同じブラウザで行ってください。
別ブラウザで GitHub を操作すると、AWS にリダイレクトされた際にデフォルトリージョン(バージニア北部等)でログインされる場合があります。

接続を作成する

  1. AWS コンソール検索(Alt+S)で CodePipeline と入力 → CodePipeline を開く
  2. 左サイドバー → 「設定」「接続」
  3. リージョンが 東京(ap-northeast-1) になっていることを確認する
  4. 接続を作成」をクリック
  5. プロバイダー: GitHub を選択
  6. 接続名: my-github-connection(任意)
  7. GitHub に接続する」をクリック

GitHub App をインストールする

クリック後、GitHub の OAuth 認証画面が開きます。

  1. Authorize」をクリック → AWS コンソールの「GitHub 接続設定」画面に自動で戻る
  2. 新しいアプリをインストールする」をクリック → GitHub の「Install & Authorize」画面が開く
  3. 「Only select repositories」 を選択 → aws-learning-projects を追加
  4. Install & Authorize」をクリック(メール認証コードが求められる場合は入力)
  5. AWS コンソールに自動でリダイレクトされる → 「接続」ボタンをクリック

接続 ARN を確認する

接続一覧から作成した接続の ARN をコピーします。

arn:aws:codeconnections:ap-northeast-1:123456789012:connection/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

重要: ステータスが 「利用可能」 になっていることを確認してから次に進んでください。
「保留中」のままの場合は接続を選択して「保留中の接続を更新する」をクリックします。

控えておく情報: 接続 ARN(arn:aws:codeconnections:...


④ cdk.json の設定

cdk.jsoncontext セクションを自分の環境に合わせて編集します。

{
  "context": {
    "employee_id": "my",
    "my_ip": "203.0.113.1/32",
    "db_password": "Handson1234!",
    "key_name": "my-cdk3-key",
    "tomcat_version": "10.1.28",
    "github_owner": "your-github-username",
    "github_repo": "aws-learning-projects",
    "github_branch": "main",
    "connection_arn": "arn:aws:codeconnections:ap-northeast-1:..."
  }
}
設定項目説明
employee_idmyリソース名のプレフィックス(my-cdk3-xxx という名前になる)
my_ip⓪で確認したIP /32EC2へのSSHを許可するIP
key_namemy-cdk3-key①で作成したキーペア名
github_ownerGitHub ユーザー名リポジトリのオーナー名(または Org 名)
github_repoaws-learning-projectsリポジトリ名
github_branchmain監視するブランチ名
connection_arn③で確認した ARNCodeConnections の接続 ARN

cdk-custom-constructs(前回)と同時にデプロイしてもリソース名が競合しません。前回は my-cdk2-xxx、今回は my-cdk3-xxx というプレフィックスになります。


⑤ コードを GitHub にプッシュする

パイプラインはリポジトリのコードを監視します。まず現在の変更(cdk.json の更新)を push しておきます。

cd C:\my-aws\aws-learning-projects
git add cdk-pipelines/cdk.json
git commit -m "chore: cdk-pipelines の cdk.json を設定"
git push origin main

⑥ パイプラインスタックのデプロイ(初回のみ)

CDK Pipelines ではパイプライン自体を最初に1回だけ手動でデプロイします。以降はパイプラインが自動的に動作します。

cd C:\my-aws\aws-learning-projects\cdk-pipelines

.venv\Scripts\activate

cdk deploy

「Do you wish to deploy these changes?」に y を入力します。

所要時間: パイプラインスタック自体のデプロイは 3〜5 分

デプロイ完了後、CodePipeline が自動起動します:

ステージ内容
SourceGitHub から最新コードを取得
BuildCodeBuild で cdk synth を実行→ Cloud Assembly を生成
Mutateパイプライン自身を最新定義に更新(セルフミューテーション)
DeployCloudFormation で ThreeTierStack(ALB + EC2 + RDS)をデプロイ

所要時間: RDS の作成に 15〜20 分かかります。


⑦ パイプラインの実行状況を確認する

  1. AWS コンソール → CodePipeline を開く
  2. my-cdk3-pipeline を選択
  3. 各ステージが 「成功」 になるまで待つ

実行履歴に「失敗」が表示されている場合:
パイプライン作成直後(GitHub App インストール前)に自動実行された結果が残っている場合があります。
確認すべき実行は「Webhook」トリガーの最新のもののみです。

CloudFormation スタックの命名規則

CDK Pipelines でステージをデプロイすると、CloudFormation スタック名は以下の形式になります:

{StageName}-{StackName}
要素このハンズオンでの値
StageNameDeploypipeline_stack.py でステージを追加した際の名前)
StackNameThreeTierStackthree_tier_stack.py のクラス名)
結果Deploy-ThreeTierStack

CdkPipelinesStack(パイプライン)と Deploy-ThreeTierStack(インフラ)の 2つが別スタックとして CloudFormation に表示されます。これは想定通りです。

CloudFormation Outputs の確認

Deploy ステージが完了したら、インフラスタックの Outputs を確認します。

aws cloudformation describe-stacks ^
  --stack-name Deploy-ThreeTierStack ^
  --region ap-northeast-1 ^
  --query "Stacks[0].Outputs"

控えておく情報: ALBEndpointEC2PublicIPRDSEndpoint


⑧ 動作確認

8-1. ALB 経由でWebアクセス確認

Outputs の ALBEndpoint をブラウザで開きます。

EC2 が作成されてから Tomcat が起動するまで 10〜15 分かかります(UserData で Java・Tomcat のインストールが実行されるため)。Deploy ステージ完了直後は 502 Bad Gateway が表示されることが多いです。しばらく待ってリトライしてください。

以下が表示されれば正常です:

AP Server - my-cdk3 3-Tier Web
Deployed via AWS CDK Pipelines (auto-deployed on git push).

8-2. EC2 に SSH 接続する

Outputs の SSHCommand を実行します。

ssh -i %USERPROFILE%\.ssh\my-cdk3-key.pem ec2-user@(EC2PublicIP)

8-3. EC2 から RDS への接続確認

EC2 に SSH 接続後(以下は EC2 上での操作):

sudo dnf install -y mariadb105

DB_PASSWORD=$(aws ssm get-parameter \
  --name /my/cdk3/db-password \
  --query Parameter.Value \
  --output text \
  --region ap-northeast-1)

mysql -h <RDSEndpoint> -u admin -p${DB_PASSWORD} sampledb

mysql> SHOW DATABASES;
mysql> exit

8-4. SSH 接続を切断する

exit

⑨ CI/CD を体験する(インフラ変更を push で自動反映)

CDK Pipelines の醍醐味は「インフラのコードを push するだけで CloudFormation への変更が自動反映される」ことです。

注意: このハンズオンで自動デプロイできるのはインフラ(CloudFormation リソース)のみです。
HTML や WAR などのアプリファイルは対象外です(次のハンズオン cdk-webapp-pipeline で体験します)。

EC2 にタグを追加して CI/CD を確認する

EC2 タグの追加は EC2 の置き換えなし(in-place 更新)で行われるため、Tomcat が止まらず 2〜3 分でパイプラインが完了します。EC2 コンソールのタグタブで変更を目視確認できます。

stacks/three_tier_stack.py を開き、以下を追加します:

from aws_cdk import Tags

Tags.of(web.instance).add("DeployedBy", "CDK Pipelines v2")

push する

cd C:\my-aws\aws-learning-projects
git add cdk-pipelines/stacks/three_tier_stack.py
git commit -m "test: EC2 タグ追加で CDK Pipelines CI/CD を確認"
git push origin main

パイプラインの自動起動を確認する

  1. AWS コンソール → CodePipelinemy-cdk3-pipeline
  2. push 後、数十秒以内にパイプラインが自動起動することを確認
  3. Deploy ステージが完了するまで待つ(2〜3 分)

タグが反映されたことを確認する

EC2 コンソール → インスタンス → my-cdk3-ap-instance「タグ」タブ

DeployedBy = CDK Pipelines v2 が追加されていれば、インフラの CI/CD が正常に動作しています。


⑩ リソース削除

課金を止めるために、ハンズオン完了後は必ず削除します。

削除順序が重要です。パイプラインによってデプロイされたスタック(Deploy-ThreeTierStack)を先に削除してから、パイプラインスタック(CdkPipelinesStack)を削除します。

1. パイプラインで作成されたスタックを削除する

aws cloudformation delete-stack ^
  --stack-name Deploy-ThreeTierStack ^
  --region ap-northeast-1

削除完了(RDS の削除に 10〜15 分かかります)を確認:

aws cloudformation describe-stacks ^
  --stack-name Deploy-ThreeTierStack ^
  --region ap-northeast-1

「does not exist」エラーが出れば削除完了です。

2. パイプラインスタック自体を削除する

cd C:\my-aws\aws-learning-projects\cdk-pipelines

.venv\Scripts\activate

cdk destroy

「Are you sure you want to delete?」に y を入力します。

--app is required エラーが出る場合は cdk-pipelines ディレクトリで実行していません。
必ず cd C:\my-aws\aws-learning-projects\cdk-pipelines を先に実行してください。

3. アーティファクト S3 バケットを削除する(必要な場合)

CDK Pipelines が自動生成するアーティファクトバケットは手動削除が必要な場合があります。

aws s3 ls | findstr pipelineartifacts

バケットが残っている場合:

aws s3 rb s3://<バケット名> --force

4. 仮想環境の終了

deactivate

5. キーペアの削除(手動)

aws ec2 delete-key-pair ^
  --key-name my-cdk3-key ^
  --region ap-northeast-1

del %USERPROFILE%\.ssh\my-cdk3-key.pem

6. GitHub との接続を削除する(手動)

CodePipeline → 設定 → 接続 → my-github-connection → 「削除」

削除されるリソース一覧

リソース削除方法
ALB・EC2・RDS・VPC・SG・SSMdelete-stack Deploy-ThreeTierStack で削除
CodePipelinecdk destroy で削除
CodeBuild プロジェクトcdk destroy で削除
アーティファクト S3 バケット手動削除が必要な場合あり
IAM ロール(パイプライン用)cdk destroy で削除
GitHub との接続(CodeConnections)CodePipeline コンソールから手動削除

CDK Pipelines のポイント解説

なぜ cdk deploy は初回だけ必要なのか

パイプラインが存在しない状態では GitHub push を検知できません。初回の cdk deploy でパイプライン自体を作成する必要があります。以降はパイプラインが自分自身を更新(セルフミューテーション)するため、再度 cdk deploy を手動実行する必要はありません。

Stage クラスの役割

# stages/three_tier_stage.py
class ThreeTierStage(cdk.Stage):
    def __init__(self, ...):
        super().__init__(...)
        ThreeTierStack(self, "ThreeTierStack")  # ← Stage に含めるスタック

Stage に複数スタックを含めると、パイプラインが順序制御してデプロイします:

class MultiStackStage(cdk.Stage):
    def __init__(self, ...):
        super().__init__(...)
        NetworkStack(self, "NetworkStack")  # ← 先にデプロイ
        AppStack(self, "AppStack")          # ← Network の後にデプロイ

モノレポでの primary_output_directory

このリポジトリは複数ハンズオンが共存するモノレポ構成のため、cdk synth をサブディレクトリで実行する設定が必要です:

CodeBuildStep(
    "Synth",
    commands=[
        "cd cdk-pipelines",        # ← サブディレクトリに移動
        "pip install -r requirements.txt",
        "npx cdk synth",
    ],
    primary_output_directory="cdk-pipelines/cdk.out",  # ← cdk.out の場所を指定
)

トラブルシューティング

症状原因対処
connection_arn が見つからないエラーcdk.json に ARN を設定していない③で確認した接続 ARN を cdk.json に設定
Source ステージが「失敗」GitHub との接続が「保留中」のままCodePipeline → 設定 → 接続 → 承認して「利用可能」にする
Build ステージが失敗github_ownergithub_repo が不正cdk.json の値を確認
Deploy ステージが失敗Bootstrap 未実施cdk bootstrap を実行してから再 push
ALB にアクセスすると 502UserData でのインストール実行中10〜15 分待ってリトライ。EC2 に SSH して sudo tail -f /var/log/user-data.log で進捗確認
パイプラインが自動起動しない接続が「保留中」または branch 名が違う接続を承認 / github_branch を確認
cdk destroy--app is requiredcdk-pipelines ディレクトリ以外で実行cd C:\my-aws\aws-learning-projects\cdk-pipelines を先に実行

パイプライン失敗時のログ確認(CodeBuild):

  1. AWS コンソール → CodePipeline → my-cdk3-pipeline
  2. 失敗したステージの「詳細」→「ログを表示」をクリック
  3. CloudWatch Logs でエラーを確認

まとめ

ステップ内容
①②キーペア作成 + Python 仮想環境のセットアップ
CodeConnections で GitHub との接続を作成・承認(「利用可能」を確認)
cdk.jsongithub_ownergithub_repoconnection_arn を設定
変更を GitHub に push してリポジトリに反映
cdk deploy初回のみ手動)でパイプラインスタックをデプロイ
CodePipeline が自動起動 → Synth → Mutate → Deploy(RDS 待ち 15〜20 分)
ALB DNS 名でアクセス → EC2 → RDS への接続テスト
EC2 タグ追加を push → パイプライン自動起動 → タグ反映を確認(CI/CD 体験)
delete-stack Deploy-ThreeTierStackcdk destroy の順で削除

CDK Pipelines の最大のメリットは「インフラのコードが唯一の変更手段になる」点です。誰かが AWS コンソールで手動変更しても、次の push でコードの状態に戻されます。これにより環境の一貫性を保てます。

今回はインフラの CI/CD のみを体験しました。アプリ(Java WAR ファイル)の自動デプロイを体験したい場合は、次のハンズオン cdk-webapp-pipeline(CodeDeploy を使用)で体験できます。

コンソールで3層構成を視覚的に学びたい場合は AWSコンソール版ハンズオン、CDK の基本は CDK版ハンズオン(cdk-alb-ec2-rds)、カスタム Construct は CDK カスタム Construct ハンズオン を参照してください。

コメント