はじめに
この記事では、AWS CodePipeline、CodeBuild、ECR、ECS Fargateを使って、GitHubにpushするだけで自動的にnginxコンテナがデプロイされる環境を構築します
ALBやRDSなどの複雑な構成は使わず、最小限のサービスだけで動作するシンプルな構成です
この記事でわかること
- AWS CodePipelineの基本的な使い方
- ECS Fargateへの自動デプロイ方法
- nginxコンテナの構築とデプロイ
- GitHub連携によるCI/CD環境の構築
前提条件
- AWSアカウントを持っている
- AWS CLIがセットアップ済み
- GitHubアカウントを持っている
- 基本的なDockerの知識がある
前提記事: AWS CLIのインストールから基本的な使い方まで徹底解説
なお、本記事で使用するソースコードは、以下のGitHubリポジトリからダウンロードできます
nginx-ecs-app(GitHubリポジトリ)
AWS サービスの役割
| サービス | 役割 | 従来構成のツール |
|---|---|---|
| CodePipeline | CI/CD パイプライン全体の管理 | GitHub Actions ワークフロー |
| CodeBuild | テスト・ビルドの実行 | GitHub Actions の test/build ジョブ |
| CodeDeploy | デプロイの実行 | GitHub Actions の deploy ジョブ |
| ECR | Docker イメージの保存 | Docker Hub |
| ECS Fargate | コンテナの実行 | EC2 / VPS / オンプレ + Docker |
従来構成の記事:GitHub Actions + Docker + ローカルPCでCI/CDパイプラインを構築し自動デプロイする
関連記事:GitHub Actions + Docker + AWS EC2でWebアプリのCI/CDパイプラインを構築し自動デプロイする
今回の構成
この記事では、以下の構成で CI/CD パイプラインを構築します
[開発者]
↓ Git push
[GitHub] ← ソースコード管理(リポジトリ)
↓ Webhook / 変更検知
[AWS CodePipeline] ← CI/CDパイプライン(処理の全体制御)
↓ Source Stage(GitHubからコード取得)
[AWS CodeBuild] ← ビルド環境(Dockerイメージをビルド)
↓ docker build / docker push
[Amazon ECR] ← コンテナレジストリ(Dockerイメージを保存)
↓ Deploy Stage
[AWS ECS Service] ← コンテナの起動数や更新を管理
↓ Task起動
[AWS ECS Fargate] ← サーバーレスコンテナ実行環境
↓ HTTP通信
[ユーザー] ← ブラウザでアプリケーションへアクセス
処理の流れ:
この構成では、以下の手順でアプリケーションが自動的にデプロイされます
-
開発者が GitHub リポジトリにコードを push
開発者がローカル環境でアプリケーションのコードをGitHubリポジトリへ git push を実行します
GitHubはソースコードを管理するリポジトリとして機能します -
GitHub の変更をトリガーに CodePipeline が起動
GitHubリポジトリに変更があると、Webhookまたはポーリングによって AWS CodePipeline がその変更を検知します
CodePipelineはCI/CDパイプラインの全体制御を行うサービスであり、パイプラインの実行を開始します -
CodePipeline が GitHub からソースコードを取得
CodePipelineの Source Stage が実行され、GitHubリポジトリから最新のソースコードを取得します
取得されたコードは、次のビルド工程へ渡されます -
CodeBuild が Docker イメージをビルド
CodePipelineは Build Stage として AWS CodeBuild を起動します
CodeBuildは一時的なビルド環境を作成し、buildspec.yml に記述された手順に従って処理を実行します
主な処理は次の通りです
・Dockerfile を使用してコンテナイメージをビルド
・Amazon ECRへログイン
・作成したDockerイメージにタグを付与 -
Dockerイメージを Amazon ECR に push
CodeBuildでビルドされたDockerイメージは、Amazon ECR(Elastic Container Registry) にpushされます
ECRはDockerイメージを保存するためのコンテナレジストリであり、ECSがイメージを取得する場所となります -
CodePipeline が ECS サービスを更新
次に CodePipeline の Deploy Stage が実行されます
このステージでは ECS サービスが更新され、新しいコンテナイメージを使用するように設定されます -
ECS Fargate が新しいコンテナを起動
ECS Service は指定された Task Definition をもとに、新しいコンテナを起動します。
Fargate はサーバーレスのコンテナ実行環境のため、EC2インスタンスの管理は不要です。
このとき ECS は次の処理を行います
・ECRから最新のDockerイメージを取得(pull)
・Fargate上で新しいコンテナを起動
・古いコンテナを停止(ローリングアップデート) -
ユーザーがブラウザからアプリケーションへアクセス
Fargate上で動作しているコンテナへリクエストが送信され、アプリケーションがレスポンスを返します
ディレクトリ構成
今回は、CI/CDパイプラインを構築するために、以下のシンプルなディレクトリ構成でアプリケーションを作成します
nginx-ecs-app/
├── Dockerfile
├── index.html
├── buildspec.yml
└── taskdef.json
それぞれのファイルの役割は以下の通りです
-
Dockerfile
Dockerイメージを作成するための設定ファイルです
このファイルでは、ベースイメージとして Nginx を使用し、作成した index.html をコンテナ内に配置します
CodeBuildはこのDockerfileをもとに Dockerイメージをビルドし、そのイメージを Amazon ECR にpushします -
index.html
Nginxコンテナから配信される シンプルなWebページです
今回はCI/CDパイプラインの動作確認を目的としているため、簡単なHTMLページを表示するだけの構成にしています
ブラウザからアクセスすると、このHTMLファイルの内容が表示されます -
buildspec.yml
AWS CodeBuildが実行する ビルド手順を定義する設定ファイルです
このファイルには、以下の処理が記述されています
Amazon ECRへのログイン
Dockerイメージのビルド
Dockerイメージのタグ付け
ECRへのDockerイメージpush
CodeBuildはこの buildspec.yml を読み取り、指定された手順に従ってビルド処理を実行します -
taskdef.json
Amazon ECSの タスク定義(Task Definition) を記述するJSONファイルです
タスク定義では、以下のようなコンテナ実行設定を指定します
使用するDockerイメージ
CPU・メモリ
ポート設定
ログ設定(CloudWatch Logs)
ネットワークモード
ECSはこのタスク定義をもとに、Fargate上でコンテナを起動します
手順1: プロジェクトファイルの作成
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AWS CodePipeline Demo</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.container {
background: white;
padding: 60px 80px;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
text-align: center;
animation: fadeIn 1s ease-in;
}
h1 {
color: #333;
font-size: 3em;
margin-bottom: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
p {
color: #666;
font-size: 1.2em;
margin-top: 10px;
}
.badge {
display: inline-block;
background: #667eea;
color: white;
padding: 10px 20px;
border-radius: 25px;
margin-top: 20px;
font-size: 0.9em;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
</style>
</head>
<body>
<div class="container">
<h1>Hello AWS CodePipeline</h1>
<p>自動デプロイ成功!</p>
<div class="badge">Powered by ECS Fargate</div>
</div>
</body>
</html>
Dockerfile
FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
buildspec.yml
version: 0.2
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
- REPOSITORY_URI=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME
- COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
- IMAGE_TAG=${COMMIT_HASH:=latest}
build:
commands:
- echo Build started on `date`
- echo Building the Docker image...
- docker build -t $REPOSITORY_URI:latest .
- docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
post_build:
commands:
- echo Build completed on `date`
- echo Pushing the Docker images...
- docker push $REPOSITORY_URI:latest
- docker push $REPOSITORY_URI:$IMAGE_TAG
- echo Writing image definitions file...
- printf '[{"name":"nginx-container","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
files: imagedefinitions.json
taskdef.json
{
"family": "nginx-ecs-task",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512",
"containerDefinitions": [
{
"name": "nginx-container",
"image": "<AWS_ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com/nginx-ecs-repo:latest",
"portMappings": [
{
"containerPort": 80,
"protocol": "tcp"
}
],
"essential": true,
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/nginx-ecs-task",
"awslogs-region": "<REGION>",
"awslogs-stream-prefix": "ecs"
}
}
}
],
"executionRoleArn": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/ecsTaskExecutionRole"
}
<AWS_ACCOUNT_ID>と<REGION>は、自分の環境の値に置き換えてから実行してください
cpu: 256、memory: 512は Fargate タスクに割り当てるリソース量を指定しています。この設定では 0.25 vCPU と 512MB のメモリを持つタスクが起動します
手順2: GitHubリポジトリの作成
事前準備: GitHub リポジトリの作成
- GitHub にログイン
- 右上の 「+」 → 「New repository」 をクリック
- 以下の内容を入力
Repository name: nginx-ecs-app
Public または Private を選択
Add a README file のチェックは 外す - Create repository をクリック
ローカルプロジェクトをGitHubへpush
作成したプロジェクトディレクトリ nginx-ecs-app に移動し、Gitリポジトリを初期化してGitHubへpushします
cd nginx-ecs-app
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/<GITHUB_USERNAME>/nginx-ecs-app.git
git push -u origin main
<GITHUB_USERNAME>は自分のGitHubユーザー名に置き換えてください
手順3: ECRリポジトリの作成
aws ecr create-repository --repository-name nginx-ecs-repo --region ap-northeast-1
作成されたリポジトリURIをメモしておきます
リポジトリ情報の取得
aws ecr describe-repositories --repository-names nginx-ecs-repo --region ap-northeast-1
手順4: ECSクラスターの作成
クラスターの作成
aws ecs create-cluster --cluster-name nginx-ecs-cluster --region ap-northeast-1
CloudWatch Logsグループの作成
aws logs create-log-group --log-group-name /ecs/nginx-ecs-task --region ap-northeast-1
タスク定義の登録
aws ecs register-task-definition --cli-input-json file://taskdef.json --region ap-northeast-1
ECSサービスの作成
まず、VPCとサブネットIDを確認
aws ec2 describe-vpcs --region ap-northeast-1
aws ec2 describe-subnets --region ap-northeast-1
セキュリティグループの作成
aws ec2 create-security-group \
--group-name nginx-ecs-sg \
--description "Security group for nginx ECS" \
--vpc-id <YOUR_VPC_ID> \
--region ap-northeast-1
デフォルトVPC確認
aws ec2 describe-vpcs --filters Name=isDefault,Values=true --region ap-northeast-1
<YOUR_VPC_ID>は上記コマンドで確認したVPC IDに置き換えてください
HTTP(80)ポートを開放
aws ec2 authorize-security-group-ingress \
--group-id <SECURITY_GROUP_ID> \
--protocol tcp \
--port 80 \
--cidr 0.0.0.0/0 \
--region ap-northeast-1
<SECURITY_GROUP_ID>は上記コマンドで作成されたセキュリティグループIDに置き換えてください
ECSサービスの作成
aws ecs create-service \
--cluster nginx-ecs-cluster \
--service-name nginx-ecs-service \
--task-definition nginx-ecs-task \
--desired-count 1 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[<SUBNET_ID>],securityGroups=[<SECURITY_GROUP_ID>],assignPublicIp=ENABLED}" \
--region ap-northeast-1
<SUBNET_ID>は上記コマンドで確認したサブネットIDに置き換えてください
<SECURITY_GROUP_ID>は上記で作成したセキュリティグループIDに置き換えてください
手順5: CodeBuildプロジェクトの作成
IAMロールの作成
CodeBuild用のIAMロールを作成します
trust-policy.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "codebuild.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
aws iam create-role \
--role-name CodeBuildServiceRole \
--assume-role-policy-document file://trust-policy.json
必要な権限をアタッチ
CodeBuildServiceRole
#ECR PowerUser
aws iam attach-role-policy \
--role-name CodeBuildServiceRole \
--policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPowerUser
#CloudWatch Logs
aws iam attach-role-policy \
--role-name CodeBuildServiceRole \
--policy-arn arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
CodeBuildプロジェクトの作成
aws codebuild create-project \
--name nginx-ecs-build \
--source type=GITHUB,location=https://github.com/<GITHUB_USERNAME>/nginx-ecs-app.git \
--artifacts type=NO_ARTIFACTS \
--environment type=LINUX_CONTAINER,image=aws/codebuild/standard:5.0,computeType=BUILD_GENERAL1_SMALL,privilegedMode=true \
--service-role arn:aws:iam::<AWS_ACCOUNT_ID>:role/CodeBuildServiceRole \
--region ap-northeast-1
<GITHUB_USERNAME>は自分のGitHubユーザー名に置き換えてください
<AWS_ACCOUNT_ID>は自分のAWSアカウントIDに置き換えてください
環境変数の追加
aws codebuild update-project \
--name nginx-ecs-build \
--environment type=LINUX_CONTAINER,image=aws/codebuild/standard:5.0,computeType=BUILD_GENERAL1_SMALL,privilegedMode=true,environmentVariables="[{name=AWS_DEFAULT_REGION,value=ap-northeast-1},{name=AWS_ACCOUNT_ID,value=<AWS_ACCOUNT_ID>},{name=IMAGE_REPO_NAME,value=nginx-ecs-repo}]" \
--region ap-northeast-1
<AWS_ACCOUNT_ID>は自分のAWSアカウントIDに置き換えてください
手順6: CodePipelineの作成
IAMロールの作成
CodePipeline用のIAMロールを作成
pipeline-trust-policy.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "codepipeline.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
aws iam create-role \
--role-name CodePipelineServiceRole \
--assume-role-policy-document file://pipeline-trust-policy.json
必要な権限をアタッチ
CodePipelineServiceRole
#CodePipeline FullAccess
aws iam attach-role-policy \
--role-name CodePipelineServiceRole \
--policy-arn arn:aws:iam::aws:policy/AWSCodePipeline_FullAccess
#ECS FullAccess
aws iam attach-role-policy \
--role-name CodePipelineServiceRole \
--policy-arn arn:aws:iam::aws:policy/AmazonECS_FullAccess
#CodeBuild Admin
aws iam attach-role-policy \
--role-name CodePipelineServiceRole \
--policy-arn arn:aws:iam::aws:policy/AWSCodeBuildAdminAccess
#S3 FullAccess
aws iam attach-role-policy \
--role-name CodePipelineServiceRole \
--policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
CodeBuildServiceRole
#S3 ReadOnly
aws iam attach-role-policy \
--role-name CodeBuildServiceRole \
--policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
#S3 FullAccess
aws iam attach-role-policy \
--role-name CodeBuildServiceRole \
--policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
S3バケットの作成
CodePipelineのアーティファクト保存用
aws s3 mb s3://nginx-ecs-pipeline-artifacts-<AWS_ACCOUNT_ID> --region ap-northeast-1
<AWS_ACCOUNT_ID>は自分のAWSアカウントIDに置き換えてください
S3バケット名はAWS全体で一意である必要があるため、アカウントIDを含めることで名前の重複を避けることができます
GitHub接続の作成
AWSコンソールから以下の手順で実行
- CodePipelineコンソールを開く
- 「設定」→「接続」→「接続を作成」
- 「GitHub」を選択
- 接続名を入力(例: github-connection)
- GitHubアカウントを認証
- 接続ARNをメモ
パイプラインの作成
pipeline.json:
{
"pipeline": {
"name": "nginx-ecs-pipeline",
"roleArn": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/CodePipelineServiceRole",
"artifactStore": {
"type": "S3",
"location": "nginx-ecs-pipeline-artifacts-<AWS_ACCOUNT_ID>"
},
"stages": [
{
"name": "Source",
"actions": [
{
"name": "Source",
"actionTypeId": {
"category": "Source",
"owner": "AWS",
"provider": "CodeStarSourceConnection",
"version": "1"
},
"configuration": {
"ConnectionArn": "<YOUR_CONNECTION_ARN>",
"FullRepositoryId": "<GITHUB_USERNAME>/nginx-ecs-app",
"BranchName": "main",
"OutputArtifactFormat": "CODE_ZIP"
},
"outputArtifacts": [
{
"name": "SourceOutput"
}
]
}
]
},
{
"name": "Build",
"actions": [
{
"name": "Build",
"actionTypeId": {
"category": "Build",
"owner": "AWS",
"provider": "CodeBuild",
"version": "1"
},
"configuration": {
"ProjectName": "nginx-ecs-build"
},
"inputArtifacts": [
{
"name": "SourceOutput"
}
],
"outputArtifacts": [
{
"name": "BuildOutput"
}
]
}
]
},
{
"name": "Deploy",
"actions": [
{
"name": "Deploy",
"actionTypeId": {
"category": "Deploy",
"owner": "AWS",
"provider": "ECS",
"version": "1"
},
"configuration": {
"ClusterName": "nginx-ecs-cluster",
"ServiceName": "nginx-ecs-service",
"FileName": "imagedefinitions.json"
},
"inputArtifacts": [
{
"name": "BuildOutput"
}
]
}
]
}
]
}
}
<AWS_ACCOUNT_ID>は自分のAWSアカウントIDに置き換えてください
<YOUR_CONNECTION_ARN>は前の手順で作成したGitHub接続のARNに置き換えてください
<GITHUB_USERNAME>は自分のGitHubユーザー名に置き換えてください
GitHub接続のARN取得
aws codestar-connections list-connections --region ap-northeast-1
pipeline.jsonの値を置き換えてから実行
aws codepipeline create-pipeline --cli-input-json file://pipeline.json --region ap-northeast-1
手順7: 動作確認
パイプラインの実行
GitHubにコードをpushすると自動的にパイプラインが実行されます
手動で実行する場合:
aws codepipeline start-pipeline-execution --name nginx-ecs-pipeline --region ap-northeast-1
ECSタスクのパブリックIPを確認
aws ecs list-tasks --cluster nginx-ecs-cluster --region ap-northeast-1
aws ecs describe-tasks --cluster nginx-ecs-cluster --tasks <TASK_ARN> --region ap-northeast-1
<TASK_ARN>は上記コマンドで取得したタスクARNに置き換えてください
出力からENI IDを取得し、パブリックIPを確認
aws ec2 describe-network-interfaces --network-interface-ids <ENI_ID> --region ap-northeast-1 --query 'NetworkInterfaces[0].Association.PublicIp'
<ENI_ID>は上記コマンドの出力から取得したENI IDに置き換えてください
ブラウザでアクセス
http://<PUBLIC_IP>
<PUBLIC_IP>は上記コマンドで取得したパブリックIPに置き換えてください

「Hello AWS CodePipeline」と表示されれば成功です
リソースの削除
動作確認が完了したら、不要な課金を避けるために作成したリソースを削除します
削除は作成の逆順で行うことで、依存関係のエラーを回避できます
1. CodePipelineの削除
aws codepipeline delete-pipeline --name nginx-ecs-pipeline --region ap-northeast-1
2. CodeBuildプロジェクトの削除
aws codebuild delete-project --name nginx-ecs-build --region ap-northeast-1
3. ECSサービスの削除
まず、サービスのタスク数を0に設定:
aws ecs update-service \
--cluster nginx-ecs-cluster \
--service nginx-ecs-service \
--desired-count 0 \
--region ap-northeast-1
サービスが停止したか確認:
aws ecs describe-services --cluster nginx-ecs-cluster --services nginx-ecs-service --region ap-northeast-1 --query "services[0].{desired:desiredCount,running:runningCount,pending:pendingCount}" --output table
サービスを削除:
aws ecs delete-service \
--cluster nginx-ecs-cluster \
--service nginx-ecs-service \
--force \
--region ap-northeast-1
サービスが本当に消えているか
aws ecs describe-services \
--cluster nginx-ecs-cluster \
--services nginx-ecs-service \
--region ap-northeast-1 \
--query "services[0].status" \
--output text
結果 INACTIVE ならOKです
4. ECSタスク定義の登録解除
タスク定義のリビジョンを確認:
aws ecs list-task-definitions --family-prefix nginx-ecs-task --region ap-northeast-1
タスク定義を登録解除:
aws ecs deregister-task-definition \
--task-definition nginx-ecs-task:1 \
--region ap-northeast-1
"status": "INACTIVE"になっていればOKです
:1の部分はリビジョン番号です。複数ある場合はすべて削除してください
5. ECSクラスターの削除
aws ecs delete-cluster --cluster nginx-ecs-cluster --region ap-northeast-1
6. ECRリポジトリの削除
イメージを含めてリポジトリを削除:
aws ecr delete-repository \
--repository-name nginx-ecs-repo \
--force \
--region ap-northeast-1
7. CloudWatch Logsグループの削除
aws logs delete-log-group --log-group-name /ecs/nginx-ecs-task --region ap-northeast-1
8. S3バケットの削除
バケット内のオブジェクトをすべて削除:
aws s3 rm s3://nginx-ecs-pipeline-artifacts-<AWS_ACCOUNT_ID> --recursive --region ap-northeast-1
<AWS_ACCOUNT_ID>は自分のAWSアカウントIDに置き換えてください
バケットを削除:
aws s3 rb s3://nginx-ecs-pipeline-artifacts-<AWS_ACCOUNT_ID> --region ap-northeast-1
9. セキュリティグループの削除
セキュリティグループIDを確認:
aws ec2 describe-security-groups \
--filters "Name=group-name,Values=nginx-ecs-sg" \
--query 'SecurityGroups[0].GroupId' \
--output text \
--region ap-northeast-1
セキュリティグループを削除:
aws ec2 delete-security-group \
--group-id <SECURITY_GROUP_ID> \
--region ap-northeast-1
<SECURITY_GROUP_ID>は上記コマンドで取得したセキュリティグループIDに置き換えてください
10. IAMロールの削除
まず、アタッチされているポリシーをデタッチします
CodeBuildServiceRoleのポリシーをデタッチ:
#ECR PowerUser
aws iam detach-role-policy \
--role-name CodeBuildServiceRole \
--policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPowerUser
#CloudWatch Logs
aws iam detach-role-policy \
--role-name CodeBuildServiceRole \
--policy-arn arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
#S3 ReadOnly
aws iam detach-role-policy \
--role-name CodeBuildServiceRole \
--policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
#S3 FullAccess
aws iam detach-role-policy \
--role-name CodeBuildServiceRole \
--policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
CodeBuildServiceRoleを削除:
aws iam delete-role --role-name CodeBuildServiceRole
CodePipelineServiceRoleのポリシーをデタッチ:
#CodePipeline FullAccess
aws iam detach-role-policy \
--role-name CodePipelineServiceRole \
--policy-arn arn:aws:iam::aws:policy/AWSCodePipeline_FullAccess
#ECS FullAccess
aws iam detach-role-policy \
--role-name CodePipelineServiceRole \
--policy-arn arn:aws:iam::aws:policy/AmazonECS_FullAccess
#CodeBuild Admin
aws iam detach-role-policy \
--role-name CodePipelineServiceRole \
--policy-arn arn:aws:iam::aws:policy/AWSCodeBuildAdminAccess
#S3 FullAccess
aws iam detach-role-policy \
--role-name CodePipelineServiceRole \
--policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
CodePipelineServiceRoleを削除:
aws iam delete-role --role-name CodePipelineServiceRole
11. GitHub接続の削除
接続ARNを確認:
aws codestar-connections list-connections --region ap-northeast-1
接続を削除:
aws codestar-connections delete-connection \
--connection-arn <YOUR_CONNECTION_ARN> \
--region ap-northeast-1
<YOUR_CONNECTION_ARN>は上記コマンドで取得した接続ARNに置き換えてください
12. キーペアの削除(EC2インスタンスを作成した場合)
aws ec2 delete-key-pair --key-name test-ec2-key --region ap-northeast-1
ローカルのキーファイルも削除:
rm test-ec2-key.pem
削除確認
すべてのリソースが削除されたか確認:
# ECSクラスター確認
aws ecs list-clusters --region ap-northeast-1
# ECRリポジトリ確認
aws ecr describe-repositories --region ap-northeast-1
# CodePipeline確認
aws codepipeline list-pipelines --region ap-northeast-1
# CodeBuild確認
aws codebuild list-projects --region ap-northeast-1
# S3バケット確認
aws s3 ls | grep nginx-ecs-pipeline-artifacts
これで、作成したすべてのリソースが削除され、不要な課金を防ぐことができます
トラブルシューティング
タスクが起動しない場合
CloudWatch Logsを確認
aws logs tail /ecs/nginx-ecs-task --follow --region ap-northeast-1
ビルドが失敗する場合
CodeBuildのログを確認
aws codebuild batch-get-builds --ids <BUILD_ID> --region ap-northeast-1
<BUILD_ID>はCodePipelineコンソールまたはCodeBuildコンソールで確認できるビルドIDに置き換えてください
パイプラインが失敗する場合
CodePipelineコンソールで各ステージの詳細を確認
コスト
この構成での月額コスト目安(東京リージョン):
- ECS Fargate(0.25 vCPU, 0.5 GB): 約$10/月
- ECR: 0.5 GB以下なら無料
- CodePipeline: 1パイプライン無料
- CodeBuild: 100分/月まで無料
- S3: 数円程度
合計: 約$10-15/月
まとめ
AWS CodePipeline + ECS Fargateを使って、GitHubにpushするだけで自動デプロイされる環境を構築しました
この構成をベースに、以下のような拡張も可能です:
- ALBを追加してHTTPS対応
- RDSを追加してデータベース連携
- CloudFrontを追加してCDN配信
- Auto Scalingを設定して負荷に応じたスケーリング
シンプルな構成から始めて、必要に応じて機能を追加していくのがおすすめです
