Claude Code × AWS CodePipeline入門: stage/action/artifactから本番承認まで
Claude CodeでAWS CodePipelineを安全に設計。stage/action/artifact、CodeBuild、承認、失敗確認まで解説。
「GitHub Actions でいいじゃん、なんでわざわざ AWS CodePipeline を使うの?」——これはよく聞かれる質問です。
答えは AWS リソースとの統合の深さにあります。ECRへのプッシュ、ECSへのデプロイ、CloudFormationスタックの更新——これらをAWSネイティブで完結させたい場合、CodePipeline + CodeBuildの組み合わせが最もシームレスです。
私は業務で複数のAWSサービスを組み合わせたパイプラインを管理していますが、Claude Code にパイプライン要件を伝えるだけで、buildspec.yml・CDKコード・IAMポリシーが一式生成されるようになってから、新規パイプラインの構築時間が1/4になりました。
CodePipeline / CodeBuild の基本構造
CodePipeline (オーケストレーター)
│
├─ Source ステージ: GitHub / CodeCommit からコードを取得
├─ Build ステージ: CodeBuild でビルド・テスト・Docker イメージ作成
├─ Test ステージ: 統合テスト・セキュリティスキャン (オプション)
└─ Deploy ステージ: ECS / Elastic Beanstalk / S3 にデプロイ
CodeBuild は buildspec.yml に記述したコマンドを実行します。GitHub Actions の steps: に相当するものと考えると理解しやすいです。
ステップ1: buildspec.yml を自動生成
claude -p "
以下の条件で CodeBuild の buildspec.yml を生成して。
【ビルド内容】
- Node.js 20 環境
- npm ci でインストール
- TypeScript のビルド (npm run build)
- ユニットテスト実行 (npm test)
- Docker イメージをビルドして ECR にプッシュ
- イメージタグ: CODEBUILD_RESOLVED_SOURCE_VERSION (Git SHA)
- latest タグも同時に付与
【セキュリティスキャン】
- ECR イメージプッシュ後に Trivy でスキャン
- HIGH/CRITICAL 脆弱性があればビルド失敗
【アーティファクト】
- imagedefinitions.json を出力 (ECS デプロイ用)
"
生成される buildspec.yml:
version: 0.2
env:
variables:
AWS_DEFAULT_REGION: ap-northeast-1
ECR_REPO_NAME: myapp
parameter-store:
ECR_REGISTRY: /myapp/ecr-registry
phases:
install:
runtime-versions:
nodejs: 20
commands:
- echo "Installing dependencies..."
- npm ci
pre_build:
commands:
- echo "Running tests..."
- npm test
- echo "Logging in to Amazon ECR..."
- aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_REGISTRY
- IMAGE_TAG=$CODEBUILD_RESOLVED_SOURCE_VERSION
- IMAGE_URI=$ECR_REGISTRY/$ECR_REPO_NAME:$IMAGE_TAG
build:
commands:
- echo "Building TypeScript..."
- npm run build
- echo "Building Docker image..."
- docker build -t $IMAGE_URI -t $ECR_REGISTRY/$ECR_REPO_NAME:latest .
post_build:
commands:
- echo "Pushing image to ECR..."
- docker push $IMAGE_URI
- docker push $ECR_REGISTRY/$ECR_REPO_NAME:latest
- echo "Scanning image for vulnerabilities..."
- |
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy:latest image \
--exit-code 1 \
--severity HIGH,CRITICAL \
$IMAGE_URI
- echo "Creating imagedefinitions.json..."
- printf '[{"name":"app","imageUri":"%s"}]' $IMAGE_URI > imagedefinitions.json
artifacts:
files:
- imagedefinitions.json
reports:
test-reports:
files:
- "coverage/junit.xml"
file-format: JUNITXML
ステップ2: CDK でパイプライン全体を構築
claude -p "
lib/pipeline-stack.ts に以下の CodePipeline を CDK TypeScript で実装して。
【パイプライン構成】
- Source: GitHub (owner/repo の main ブランチ)
- Build: CodeBuild (上の buildspec.yml を使用)
- Deploy: ECS サービスへの Blue/Green デプロイ
【通知】
- パイプライン失敗時に SNS → Slack に通知
- デプロイ成功時にも Slack に通知
【アーティファクトストア】
- S3 バケット (暗号化・バージョニング有効)
"
// lib/pipeline-stack.ts
import * as cdk from "aws-cdk-lib";
import * as codepipeline from "aws-cdk-lib/aws-codepipeline";
import * as codepipeline_actions from "aws-cdk-lib/aws-codepipeline-actions";
import * as codebuild from "aws-cdk-lib/aws-codebuild";
import * as s3 from "aws-cdk-lib/aws-s3";
import * as iam from "aws-cdk-lib/aws-iam";
import * as sns from "aws-cdk-lib/aws-sns";
import * as ecs from "aws-cdk-lib/aws-ecs";
export class PipelineStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// アーティファクトストア S3
const artifactBucket = new s3.Bucket(this, "ArtifactBucket", {
versioned: true,
encryption: s3.BucketEncryption.S3_MANAGED,
removalPolicy: cdk.RemovalPolicy.RETAIN,
});
// アーティファクト定義
const sourceOutput = new codepipeline.Artifact("SourceOutput");
const buildOutput = new codepipeline.Artifact("BuildOutput");
// CodeBuild プロジェクト
const buildProject = new codebuild.PipelineProject(this, "BuildProject", {
buildSpec: codebuild.BuildSpec.fromSourceFilename("buildspec.yml"),
environment: {
buildImage: codebuild.LinuxBuildImage.STANDARD_7_0,
privileged: true, // Docker ビルドに必要
},
environmentVariables: {
AWS_ACCOUNT_ID: { value: this.account },
},
});
// ECR へのアクセス権を付与
buildProject.addToRolePolicy(new iam.PolicyStatement({
actions: [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
],
resources: ["*"],
}));
// パイプライン
const pipeline = new codepipeline.Pipeline(this, "Pipeline", {
pipelineName: "myapp-pipeline",
artifactBucket,
stages: [
{
stageName: "Source",
actions: [
new codepipeline_actions.GitHubSourceAction({
actionName: "GitHub_Source",
owner: "your-org",
repo: "your-repo",
branch: "main",
oauthToken: cdk.SecretValue.secretsManager("github-token"),
output: sourceOutput,
}),
],
},
{
stageName: "Build",
actions: [
new codepipeline_actions.CodeBuildAction({
actionName: "Build_and_Test",
project: buildProject,
input: sourceOutput,
outputs: [buildOutput],
}),
],
},
{
stageName: "Deploy",
actions: [
new codepipeline_actions.EcsDeployAction({
actionName: "Deploy_to_ECS",
service: ecs.FargateService.fromFargateServiceAttributes(
this, "EcsService", {
cluster: ecs.Cluster.fromClusterArn(
this, "Cluster",
`arn:aws:ecs:${this.region}:${this.account}:cluster/myapp-cluster`
),
serviceName: "myapp-service",
}
),
input: buildOutput,
}),
],
},
],
});
// 失敗通知
const alertTopic = new sns.Topic(this, "AlertTopic");
pipeline.notifyOnAnyStageStateChange("PipelineNotification", alertTopic, {
events: [
codepipeline.PipelineNotificationEvents.PIPELINE_EXECUTION_FAILED,
codepipeline.PipelineNotificationEvents.PIPELINE_EXECUTION_SUCCEEDED,
],
});
}
}
ステップ3: テスト結果レポートの設定
claude -p "
CodeBuild でテスト結果を CodeBuild Reports に送信して
PR ごとに品質レポートを確認できるようにしたい。
- テストフレームワーク: Vitest
- カバレッジレポート: Istanbul (lcov形式)
- buildspec.yml に reports セクションを追加
- CDK でレポートグループも定義
"
# buildspec.yml の reports セクション
reports:
UnitTestResults:
files:
- "test-results/junit.xml"
file-format: JUNITXML
CodeCoverage:
files:
- "coverage/lcov.info"
file-format: CLOVERXML
ステップ4: マルチ環境パイプラインの設計
claude -p "
dev → staging → prod の3環境への段階デプロイパイプラインを CDK で設計して。
- dev: main ブランチに push で自動デプロイ
- staging: dev デプロイ成功後、手動承認後にデプロイ
- prod: staging デプロイ成功後、手動承認後にデプロイ
- 各環境のデプロイ完了を Slack に通知
"
// staging → prod の手動承認ゲートを追加
{
stageName: "Approve_Staging",
actions: [
new codepipeline_actions.ManualApprovalAction({
actionName: "Approve_Deploy_to_Staging",
notificationTopic: alertTopic,
additionalInformation: "Staging へのデプロイを承認しますか?",
}),
],
},
{
stageName: "Deploy_Staging",
actions: [
new codepipeline_actions.EcsDeployAction({
actionName: "Deploy_to_Staging",
service: stagingService,
input: buildOutput,
}),
],
},
落とし穴4選
1. CodeBuild の privileged: true を忘れる
Docker イメージをビルドするには privileged: true が必須。これがないと Cannot connect to the Docker daemon エラーが出ます。
2. GitHub OAuth トークンの権限不足
GitHubソースには repo スコープが必要。public_repo だけだとプライベートリポジトリに使えません。
3. S3アーティファクトバケットのリージョン
パイプラインとアーティファクトS3バケットは同じリージョンである必要があります。クロスリージョンパイプラインは別途設定が必要。
4. ECS デプロイアクションの imagedefinitions.json 形式
ECS デプロイには正確な形式が必要です:
[{"name": "コンテナ名", "imageUri": "イメージURI"}]
コンテナ名はタスク定義のコンテナ名と完全一致させてください。
Source-Build-Test-Deployの最小構成を先に決める
CodePipelineを初心者向けに言うと、リリース作業を上から順に流すベルトコンベアです。pipelineは全体の流れ、stageはSourceやBuildのような区切り、actionはその区切りの中で実行する一つの作業、artifactは次の作業へ渡す成果物です。たとえばGitHubから取ったソースコードがSourceOutput、CodeBuildで作ったdistやzipがBuildOutputです。
AWS公式のCodePipeline conceptsでも、pipelineは複数stageで構成され、stageにはactionが入り、artifactをaction間で受け渡すと説明されています。Claude Codeへ依頼するときも、この4語を曖昧にしないだけで出力品質がかなり上がります。
最初に作るなら、Source -> Build -> Test -> Approve -> Deployの5ステージで十分です。CodePipelineの作成ガイドでは、パイプラインは少なくともSourceと、もう一つのBuildまたはDeploy stageを持つ必要があります。いきなり本番自動デプロイにせず、Production前にManual approvalを入れると、初心者でも事故を止めやすくなります。
| stage | action | artifact | 目的 |
|---|---|---|---|
| Source | GitHub / CodeStar connection | SourceOutput | mainブランチの変更を取る |
| Build | CodeBuild | BuildOutput | npm ci、テスト、ビルド、zip化 |
| Test | CodeBuild | TestOutput | smoke testやlintを分離して見る |
| Approve | Manual approval | なし | 本番反映前に人間が確認する |
| Deploy | S3 / CloudFormation / Lambda | BuildOutput | S3/CloudFrontやLambdaへ反映する |
CLIで骨格を作る場合は、次のpipeline.jsonをたたき台にします。ARN、bucket、repo、project名は自分の環境に置き換えてください。
{
"pipeline": {
"name": "webapp-main",
"roleArn": "arn:aws:iam::123456789012:role/service-role/AWSCodePipelineServiceRole-ap-northeast-1-webapp-main",
"artifactStore": { "type": "S3", "location": "my-codepipeline-artifacts-apne1" },
"stages": [
{
"name": "Source",
"actions": [{
"name": "Source",
"actionTypeId": { "category": "Source", "owner": "AWS", "provider": "CodeStarSourceConnection", "version": "1" },
"configuration": {
"ConnectionArn": "arn:aws:codestar-connections:ap-northeast-1:123456789012:connection/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"FullRepositoryId": "your-org/your-repo",
"BranchName": "main",
"OutputArtifactFormat": "CODE_ZIP"
},
"outputArtifacts": [{ "name": "SourceOutput" }],
"runOrder": 1
}]
},
{
"name": "Build",
"actions": [{
"name": "BuildAndUnitTest",
"actionTypeId": { "category": "Build", "owner": "AWS", "provider": "CodeBuild", "version": "1" },
"configuration": { "ProjectName": "webapp-build" },
"inputArtifacts": [{ "name": "SourceOutput" }],
"outputArtifacts": [{ "name": "BuildOutput" }],
"runOrder": 1
}]
},
{
"name": "ApproveProd",
"actions": [{
"name": "ApproveProduction",
"actionTypeId": { "category": "Approval", "owner": "AWS", "provider": "Manual", "version": "1" },
"configuration": { "CustomData": "Check smoke test, CloudWatch alarms, and release note before approving." },
"runOrder": 1
}]
},
{
"name": "Deploy",
"actions": [{
"name": "DeployStaticSite",
"actionTypeId": { "category": "Deploy", "owner": "AWS", "provider": "S3", "version": "1" },
"configuration": { "BucketName": "my-webapp-prod", "Extract": "true" },
"inputArtifacts": [{ "name": "BuildOutput" }],
"runOrder": 1
}]
}
]
}
}
aws codepipeline create-pipeline --cli-input-json file://pipeline.json
aws codepipeline get-pipeline --name webapp-main
aws codepipeline start-pipeline-execution --name webapp-main
S3/CloudFrontとLambdaのデプロイ例
静的サイトなら、CodeBuildでdistを作り、Deploy stageのS3 actionで展開します。CloudFrontのキャッシュ削除はS3 deploy actionだけでは終わらないので、後続のCodeBuild actionやLambda invoke actionで分けると見通しが良いです。LambdaならCodeBuildでpackageを作り、CloudFormation deploy actionまたはSAM deployで反映します。
S3/CloudFront向けのbuildspecは次の形が扱いやすいです。BuildOutputにdistを渡し、CloudFront invalidationは別アクションにしても、このままCodeBuild内で実行しても構いません。
version: 0.2
env:
variables:
AWS_REGION: ap-northeast-1
S3_BUCKET: my-webapp-prod
CLOUDFRONT_DISTRIBUTION_ID: E1234567890ABC
phases:
install:
runtime-versions:
nodejs: 20
commands:
- npm ci
pre_build:
commands:
- npm test
- npm run lint
build:
commands:
- npm run build
post_build:
commands:
- aws s3 sync ./dist s3://$S3_BUCKET/ --delete --cache-control "public,max-age=300"
- aws cloudfront create-invalidation --distribution-id $CLOUDFRONT_DISTRIBUTION_ID --paths "/*"
artifacts:
base-directory: dist
files:
- "**/*"
Lambdaの場合は、成果物をS3 artifact bucketへ置き、CloudFormationに渡す流れが読みやすいです。
version: 0.2
env:
variables:
AWS_REGION: ap-northeast-1
ARTIFACT_BUCKET: my-lambda-artifacts-apne1
phases:
install:
runtime-versions:
nodejs: 20
commands:
- npm ci
build:
commands:
- npm test
- npm run build
- zip -r function.zip dist package.json node_modules
post_build:
commands:
- aws s3 cp function.zip s3://$ARTIFACT_BUCKET/lambda/function.zip
- aws cloudformation package --template-file template.yml --s3-bucket $ARTIFACT_BUCKET --output-template-file packaged.yml
artifacts:
files:
- packaged.yml
- function.zip
実例は3つに分けると設計しやすいです。1つ目はAstroやNext.jsの静的サイトをS3/CloudFrontへ出す構成。2つ目はAPI用LambdaをCloudFormationで更新する構成。3つ目はstagingまでは自動、本番だけ承認stageを挟むチーム運用です。全部を同じstageに詰めるより、artifactの名前と責任を分けたほうが後で直せます。
失敗したときの確認観点
CodePipelineが落ちたときは、まずpipeline全体ではなくstageとactionを見ます。Sourceで落ちたなら接続ARN、branch、artifact format。Buildで落ちたならCodeBuild log、buildspec、環境変数、IAM。Deployで落ちたなら入力artifact名、S3 bucket、CloudFormation role、Lambda package、リージョンを疑います。
aws codepipeline get-pipeline-state --name webapp-main
aws codepipeline list-action-executions --pipeline-name webapp-main --max-results 5
aws codebuild batch-get-builds --ids webapp-build:BUILD_ID_FROM_ACTION_EXECUTION
aws logs tail /aws/codebuild/webapp-build --since 30m --follow
よくある失敗例は、BuildOutputという名前で出したartifactをDeploy側でSourceOutputとして読んでしまうことです。次に多いのはCodeBuildのservice roleにS3、CloudFront、CloudFormation、Lambdaの権限が足りないケースです。さらに、Parameter StoreやSecrets Managerを使わず平文の環境変数にトークンを置く失敗もあります。AWSのactions guideにある通り、actionにはSource、Build、Test、Deploy、Approval、Invokeがあるので、権限もaction単位で分けて考えるのが安全です。
Claude Codeへの安全な依頼プロンプト
Claude Codeに丸投げすると、IAMが広すぎたり、承認stageを抜いたり、CloudFront invalidationを忘れたりします。依頼文では、作ってほしいものだけでなく、禁止事項と確認コマンドも書きます。
このリポジトリに AWS CodePipeline + CodeBuild のCI/CDを追加してください。
目的:
- Source: GitHub main
- Build: CodeBuildでnpm ci、npm test、npm run build
- Test: smoke testを別CodeBuild actionで実行
- Approve: Production前にManual approvalを置く
- Deploy: distをS3へ配信し、CloudFrontをinvalidationする
制約:
- IAMにAdministratorAccessやワイルドカード権限を付けない
- 本番deployは承認stageなしで自動化しない
- secretは平文環境変数に置かず、Parameter StoreかSecrets Managerを使う
- 既存のpipelineやbucketを削除しない
成果物:
- buildspec.yml
- pipeline.jsonまたはCDK stack
- 失敗時の確認コマンド
- READMEの運用手順
検証:
- 変更前に現在の構成を説明
- diffを見せてから変更
- aws codepipeline get-pipeline-state とCodeBuild logの見方をREADMEに書く
このプロンプトは、Create a pipeline, stages, and actionsの作成手順と、Define CI/CD pipelinesの考え方に寄せています。Claude Codeには「実装して」だけでなく「どの公式概念に合わせたか」まで説明させると、レビューがかなり楽になります。
Masaの検証メモと次の導線
Masaの検証メモとして残すなら、最初に効いたのは承認stageよりもartifact名の固定でした。SourceOutput、BuildOutput、TestOutputを命名しておくだけで、失敗時にどこで壊れたか追いやすくなります。逆に、いきなりCDKで全部を抽象化すると、初心者はPipelineの画面とコードの対応が見えなくなります。最初の1本はconsoleやJSONで構造を見てからCDK化したほうが理解が速いです。
もう一つの発見は、CodePipelineの記事はAWS IAM、S3、Lambda、CloudFrontの理解と必ずつながることです。権限設計はClaude Code AWS IAMガイド、静的配信はClaude Code AWS S3入門、Lambda更新はClaude Code AWS Lambda完全ガイドも一緒に見ると、点ではなく流れで理解できます。
個人で試す段階なら、まず無料PDFでClaude Codeの基本コマンドと確認手順を手元に置いてください。CI/CDをチームに入れるなら、buildspec、IAM、承認stage、障害時の切り戻しまでセットで設計する必要があります。そこまで含めて整理したい場合は、Claude Code研修・相談で実際のAWS構成に合わせて一緒に詰められます。
まとめ
| タスク | Claude Code の貢献 |
|---|---|
| buildspec.yml 生成 | ビルド・テスト・Docker・セキュリティスキャン込みで生成 |
| CDKパイプライン | Source→Build→Deploy の全ステージを自動生成 |
| マルチ環境設計 | 手動承認ゲート付きの段階デプロイを設計 |
| テストレポート | CodeBuild Reports の設定を自動化 |
CodePipeline の設定は複雑に見えますが、Claude Code に「こういうパイプラインが欲しい」と伝えるだけで buildspec.yml も CDK コードも一式揃います。まず buildspec.yml から試してみてください。
関連記事
- Claude Code × AWS ECS/Fargate 完全ガイド
- Claude Code × AWS CloudFormation/CDK 完全ガイド
- Claude Code × AWS IAM 完全ガイド
参考資料
無料PDF: Claude Code はじめてのチートシート
まずは無料PDFで基本コマンドと最初の使い方をまとめて確認してください。登録後はそのままテンプレート集や導入相談にも進めます。
スパムは送りません。登録情報は厳重に管理します。
Claude Codeを仕事で使える形にしませんか?
無料PDFで基礎を固めたあと、すぐ使えるテンプレート集で試し、必要なら業務自動化や導入相談まで進められます。
この記事を書いた人
Masa
Claude Codeの実務活用、導入設計、収益導線改善を検証しているエンジニア。10言語の技術メディアを運営中。
関連書籍・参考図書
この記事のテーマに関連する書籍を楽天ブックスで探せます。
※ 当サイトは楽天市場のアフィリエイトプログラムに参加しています。上記リンクから商品をご購入いただくと、運営者に紹介料が支払われる場合があります。
関連記事
ObsidianメモをCLAUDE.mdに変えるClaude Code運用: 文脈を毎回説明しない仕組み
Obsidianの作業メモからCLAUDE.md用の運用ノートを作り、Claude Codeに安定した文脈を渡す方法。
Claude Code Revenue CTA Routing: 記事からPDF、Gumroad、相談へ送る設計
PVだけで終わらせず、読者の状態に合わせて無料PDF、Gumroad教材、導入相談へ分岐するCTA設計です。
Claude Codeチーム引き継ぎルール: レビュー、権限、収益導線まで渡す実務手順
Claude Codeの作業をチームで渡すための証拠、権限、ロールバック、無料PDF/Gumroad/相談導線の実務ルール。