- はじめに
- CI/CDとは
- AWS CI/CDサービスの概要
- CodePipelineの基本
- CI/CDパイプライン構築の例
- CI/CDパイプラインの応用例
- AWS CloudFormationによるパイプラインの自動化
- パイプラインのモニタリングと分析
- セキュリティのベストプラクティス
- CI/CDパイプラインの最適化
- トラブルシューティング
- まとめ
- 参考リソース
はじめに
現代のソフトウェア開発では、継続的インテグレーション/継続的デリバリー(CI/CD)の実践が不可欠となっています。AWSは、CodePipelineをはじめとする一連のサービスを提供し、クラウドネイティブなCI/CDパイプラインの構築を強力にサポートしています。
本記事では、AWS CodePipelineを中心としたCI/CDパイプラインの構築方法について、基本的な概念から実践的な手順、応用例まで詳しく解説します。
CI/CDとは
始めに、CI/CDの基本概念を簡単におさらいしておきましょう。
- 継続的インテグレーション(CI): 開発者がコードの変更を頻繁に共有リポジトリにマージし、自動的にビルドとテストを実行することで、早期に問題を発見する手法
- 継続的デリバリー(CD): ビルドとテストを通過したコードを自動的に本番環境に近い環境にデプロイし、いつでもリリース可能な状態を維持する手法
- 継続的デプロイメント(CD): さらに踏み込んで、変更を自動的に本番環境にデプロイする手法
AWS CI/CDサービスの概要
AWSのCI/CDサービスには主に以下のものがあります:
- AWS CodePipeline: パイプラインの定義と管理、各ステージの連携を担当
- AWS CodeCommit: Gitベースのプライベートリポジトリサービス
- AWS CodeBuild: ソースコードのビルドとテストを行うフルマネージドサービス
- AWS CodeDeploy: さまざまな環境へのデプロイを自動化するサービス
- AWS CodeStar: 上記サービスを統合したプロジェクト管理サービス
- AWS CodeArtifact: プライベートなアーティファクトリポジトリサービス
これらを組み合わせることで、コードのコミットからテスト、デプロイまでを自動化する完全なCI/CDパイプラインを構築できます。
CodePipelineの基本
AWS CodePipelineは、CI/CDパイプラインの定義、視覚化、自動化を行うサービスです。主な特徴は以下の通りです:
- ステージベースのワークフロー: ソース取得、ビルド、テスト、デプロイなど、複数のステージで構成
- 豊富な統合: AWSサービスだけでなく、GitHub、Jenkins、Spinnaker等のサードパーティーツールとも連携可能
- 並列アクション: 同じステージ内で複数のアクションを並列実行可能
- 承認アクション: 人による手動承認ステップの追加が可能
- 可視化: パイプラインの実行状況をコンソールで視覚的に確認可能
CI/CDパイプライン構築の例
それでは実際に、AWSのサービスを使ったCI/CDパイプラインの構築手順を見ていきましょう。この例では、以下のフローを実装します:
- GitHubからソースコードを取得
- CodeBuildでビルドとテストを実行
- テスト環境へのデプロイ
- 手動承認
- 本番環境へのデプロイ
前提条件
- AWSアカウント
- GitHubアカウントとリポジトリ
- AWS CLIのセットアップ(任意)
- デプロイ対象のアプリケーション
手順1:必要なIAMロールの作成
まず、CodePipelineとCodeBuildが使用するIAMロールを作成します。AWSマネジメントコンソールから作成する方法と、AWS CloudFormationテンプレートを使用する方法があります。
CodePipeline用IAMロール(AWSコンソール)
- IAMコンソールを開き、「ロール」→「ロールの作成」をクリック
- 「AWSサービス」を選択し、「CodePipeline」を選択して「次へ」
- 「AWSCodePipelineServiceRole」ポリシーを選択して「次へ」
- ロール名(例:
CodePipelineServiceRole
)を入力して「ロールの作成」をクリック
CodeBuild用IAMロール(AWSコンソール)
- IAMコンソールで「ロール」→「ロールの作成」をクリック
- 「AWSサービス」を選択し、「CodeBuild」を選択して「次へ」
- 「AmazonS3FullAccess」と「AWSCodeBuildAdminAccess」ポリシーを選択して「次へ」
- ロール名(例:
CodeBuildServiceRole
)を入力して「ロールの作成」をクリック
手順2:アーティファクト保存用のS3バケットを作成
CodePipelineは、各ステージ間でアーティファクトを受け渡すためのS3バケットを必要とします。
aws s3 mb s3://my-codepipeline-artifacts-bucket --region ap-northeast-1
または、AWSコンソールからS3バケットを作成します。
手順3:CodeBuildプロジェクトの作成
次に、ソースコードのビルドとテストを行うCodeBuildプロジェクトを作成します。
- CodeBuildコンソールを開き、「ビルドプロジェクトを作成する」をクリック
- プロジェクト名(例:
MyAppBuild
)を入力 - ソースプロバイダーを設定(この時点では任意の設定で可、後でパイプラインから上書きされる)
- 環境設定:
- マネージドイメージを選択(例: Amazon Linux 2、標準)
- サービスロールには先ほど作成した「CodeBuildServiceRole」を選択
- Buildspec:
- 「buildspec.ymlを使用する」を選択(または、インラインでコマンドを定義)
- アーティファクト:
- タイプ: 「Amazon S3」を選択
- バケット名: 先ほど作成したS3バケットを選択
- 名前:
BuildOutput
などと入力
- 「ビルドプロジェクトの作成」をクリック
手順4:buildspec.ymlの作成
アプリケーションのリポジトリにbuildspec.yml
ファイルを作成します。これはCodeBuildが実行する命令を定義するファイルです。以下は、Node.jsアプリケーションの例です:
version: 0.2
phases:
install:
runtime-versions:
nodejs: 16
commands:
- echo Installing dependencies...
- npm install
pre_build:
commands:
- echo Running tests...
- npm test
build:
commands:
- echo Building the application...
- npm run build
post_build:
commands:
- echo Build completed on `date`
artifacts:
files:
- build/**/*
- node_modules/**/*
- scripts/**/*
- appspec.yml
- package.json
discard-paths: no
手順5:CodePipelineの作成
いよいよ、CodePipelineを作成します。
- CodePipelineコンソールを開き、「パイプラインの作成」をクリック
- パイプライン名(例:
MyAppPipeline
)を入力して「次へ」 - サービスロールは先ほど作成した「CodePipelineServiceRole」を選択
- アーティファクトストアとして、先ほど作成したS3バケットを選択して「次へ」
ソースステージの設定:
- ソースプロバイダーとして「GitHub(バージョン2)」を選択
- 「接続」で「Connect to GitHub」をクリックし、認証を行う
- リポジトリとブランチを選択
- 変更検出オプションとして「GitHub Webhooks」を選択して「次へ」
ビルドステージの設定:
- ビルドプロバイダーとして「AWS CodeBuild」を選択
- リージョンを選択
- 先ほど作成したビルドプロジェクト「MyAppBuild」を選択して「次へ」
デプロイステージ(テスト環境)の設定:
- デプロイプロバイダーとして「AWS CodeDeploy」を選択
- リージョンを選択
- CodeDeployアプリケーション名とデプロイグループ名を入力(未作成の場合は先に作成が必要)
- 「次へ」をクリックし、設定内容を確認して「パイプラインの作成」をクリック
手順6:手動承認ステージの追加
テスト環境へのデプロイ後、本番環境へのデプロイ前に手動承認を追加します。
- 作成したパイプラインの詳細ページで「編集」をクリック
- テスト環境デプロイステージの後に「+ステージを追加」をクリック
- ステージ名(例:
Approval
)を入力して「ステージを追加」 - 追加したステージ内で「+アクションを追加」をクリック
- アクション名(例:
ManualApproval
)を入力 - アクションプロバイダーとして「手動承認」を選択
- 通知オプションとして、必要に応じてSNSトピックを設定
- 「完了」をクリックし、「保存」をクリック
手順7:本番環境デプロイステージの追加
手動承認ステージの後に、本番環境へのデプロイステージを追加します。
- 承認ステージの後に「+ステージを追加」をクリック
- ステージ名(例:
Production
)を入力して「ステージを追加」 - 「+アクションを追加」をクリック
- アクション名(例:
DeployToProduction
)を入力 - アクションプロバイダーとして「AWS CodeDeploy」を選択
- 本番環境用のCodeDeployアプリケーションとデプロイグループを選択
- 「完了」をクリックし、「保存」をクリック
手順8:CodeDeployのセットアップ
CodeDeployを使用するには、デプロイ先の環境設定とappspec.yml
ファイルの作成が必要です。
appspec.ymlの例(EC2デプロイの場合):
version: 0.0
os: linux
files:
- source: /
destination: /var/www/html/my-app
hooks:
BeforeInstall:
- location: scripts/before_install.sh
timeout: 300
runas: root
AfterInstall:
- location: scripts/after_install.sh
timeout: 300
runas: root
ApplicationStart:
- location: scripts/application_start.sh
timeout: 300
runas: root
EC2インスタンスのセットアップ:
- CodeDeployエージェントをインストール
- IAMインスタンスプロファイルを設定
- タグを設定(CodeDeployデプロイグループの対象特定用)
CI/CDパイプラインの応用例
基本的なパイプラインの構築方法を理解したところで、いくつかの応用例を紹介します。
1. マルチ環境デプロイメント
開発、ステージング、本番環境など、複数の環境へ段階的にデプロイするパイプラインを構築できます。
GitHub → Build → Dev Deploy → Dev Tests → Staging Deploy → Staging Tests → Approval → Production Deploy
2. パラレルテスト実行
ビルド後に複数のテストを並列で実行し、効率的に品質を確保するパイプラインです。
GitHub → Build → [Unit Tests, Integration Tests, Security Scans] → Deploy
3. ブルー/グリーンデプロイメント
CodeDeployのブルー/グリーンデプロイメント機能を活用し、ダウンタイムなしでの安全なデプロイを実現します。
GitHub → Build → Test → Blue/Green Deploy → Traffic Shift → Terminate Old Version
4. クロスアカウントデプロイメント
開発アカウントと本番アカウントを分離し、セキュリティを強化したパイプラインです。
[開発アカウント] GitHub → Build → Test → [本番アカウント] Production Deploy
5. インフラストラクチャのCI/CD
AWS CloudFormationやTerraformを使用して、インフラストラクチャのCI/CDを実現します。
GitHub → Validate Templates → Create Change Sets → Approval → Apply Changes
AWS CloudFormationによるパイプラインの自動化
これまでの手順をAWS CloudFormationテンプレートで自動化することもできます。以下は、簡略化したテンプレートの例です:
AWSTemplateFormatVersion: '2010-09-09'
Description: 'CI/CD Pipeline with AWS CodePipeline, CodeBuild, and CodeDeploy'
Parameters:
GitHubOwner:
Type: String
GitHubRepo:
Type: String
GitHubBranch:
Type: String
Default: main
GitHubToken:
Type: String
NoEcho: true
Resources:
# アーティファクトバケット
ArtifactBucket:
Type: AWS::S3::Bucket
Properties:
VersioningConfiguration:
Status: Enabled
# CodePipelineサービスロール
CodePipelineServiceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: codepipeline.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AWSCodeStarFullAccess'
# CodeBuildプロジェクト
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Name: !Sub ${AWS::StackName}-Build
ServiceRole: !GetAtt CodeBuildServiceRole.Arn
Artifacts:
Type: CODEPIPELINE
Environment:
Type: LINUX_CONTAINER
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0
Source:
Type: CODEPIPELINE
BuildSpec: buildspec.yml
# CodeBuildサービスロール
CodeBuildServiceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: codebuild.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AmazonS3FullAccess'
- 'arn:aws:iam::aws:policy/AWSCodeBuildAdminAccess'
# CodePipeline
Pipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
RoleArn: !GetAtt CodePipelineServiceRole.Arn
ArtifactStore:
Type: S3
Location: !Ref ArtifactBucket
Stages:
# ソースステージ
- Name: Source
Actions:
- Name: Source
ActionTypeId:
Category: Source
Owner: ThirdParty
Provider: GitHub
Version: '1'
Configuration:
Owner: !Ref GitHubOwner
Repo: !Ref GitHubRepo
Branch: !Ref GitHubBranch
OAuthToken: !Ref GitHubToken
OutputArtifacts:
- Name: SourceCode
# ビルドステージ
- Name: Build
Actions:
- Name: BuildAndTest
ActionTypeId:
Category: Build
Owner: AWS
Provider: CodeBuild
Version: '1'
Configuration:
ProjectName: !Ref CodeBuildProject
InputArtifacts:
- Name: SourceCode
OutputArtifacts:
- Name: BuildOutput
# デプロイステージ(テスト環境)
- Name: DeployToTest
Actions:
- Name: DeployAction
ActionTypeId:
Category: Deploy
Owner: AWS
Provider: CodeDeploy
Version: '1'
Configuration:
ApplicationName: !Ref ApplicationName
DeploymentGroupName: !Ref TestDeploymentGroup
InputArtifacts:
- Name: BuildOutput
Outputs:
PipelineURL:
Description: URL to the CodePipeline Console
Value: !Sub https://console.aws.amazon.com/codepipeline/home?region=${AWS::Region}#/view/${Pipeline}
パイプラインのモニタリングと分析
CI/CDパイプラインの効率性と信頼性を向上させるためには、モニタリングと分析が重要です。
CloudWatchによるモニタリング
CodePipelineは、パイプラインの実行状況をCloudWatchに自動的に送信します。これを活用して、以下のようなモニタリングが可能です:
- パイプライン実行の成功率/失敗率
- 各ステージの実行時間
- ビルドの成功/失敗
- デプロイの成功/失敗
CloudWatch Dashboardの作成
以下のような指標を含むダッシュボードを作成することで、パイプラインの健全性を一目で確認できます:
- パイプライン実行数(成功/失敗)
- 平均実行時間
- コミットからデプロイまでのリードタイム
- 障害発生後の平均復旧時間(MTTR)
アラートの設定
重要な問題を早期に検知するために、以下のようなアラートを設定することをお勧めします:
- パイプライン実行失敗時のアラート
- パイプライン実行時間閾値超過時のアラート
- 手動承認待ち状態が一定時間継続した場合のアラート
セキュリティのベストプラクティス
CI/CDパイプラインのセキュリティを強化するための重要なベストプラクティスをいくつか紹介します:
- 最小権限の原則: 各サービスに必要最小限の権限のみを付与する
- 機密情報の保護: パスワードやAPIキーなどの機密情報はAWS Secrets Managerで管理する
- コード品質のチェック: SonarQubeなどのツールを統合し、セキュリティ脆弱性を検出する
- イメージスキャン: コンテナイメージの脆弱性スキャンを実施する
- インフラストラクチャのコード化: CloudFormationやTerraformを使用し、インフラストラクチャをコード管理する
- 監査ログの有効化: AWS CloudTrailを有効化し、API呼び出しを記録する
CI/CDパイプラインの最適化
パイプラインのパフォーマンスと効率を最適化するためのポイントをいくつか紹介します:
- ビルドキャッシュの活用: CodeBuildのキャッシュ機能を使用して、依存関係のダウンロード時間を短縮
- 並列処理の活用: 独立したタスクは並列実行することで全体の実行時間を短縮
- テストの最適化: テストを重要度に応じて分類し、クリティカルなテストを優先して実行
- アーティファクトサイズの最適化: 必要なファイルのみをアーティファクトに含める
- デプロイ戦略の最適化: 適切なデプロイ戦略(ローリング、ブルー/グリーンなど)を選択
トラブルシューティング
CI/CDパイプラインで発生しやすい問題とその解決策を紹介します:
- パイプライン実行失敗:
- CodePipelineコンソールでエラーメッセージを確認
- 各ステージのログを詳細に調査
- IAM権限の問題がないか確認
- ビルド失敗:
- CodeBuildのログを確認
- buildspec.ymlの構文エラーがないか確認
- 依存関係の問題がないか確認
- デプロイ失敗:
- CodeDeployのログを確認
- appspec.ymlの構文エラーがないか確認
- デプロイスクリプトのエラーがないか確認
- ターゲット環境のアクセス権限を確認
- パフォーマンス問題:
- 各ステージの実行時間を分析
- キャッシュの活用を検討
- 並列処理の可能性を検討
まとめ
AWS CodePipelineを中心としたCI/CDパイプラインの構築について、基礎から応用まで解説しました。AWSの各種サービスを組み合わせることで、コードのコミットから本番環境へのデプロイまでを自動化し、開発プロセスの効率と品質を向上させることができます。
基本的なパイプラインから始めて、徐々に機能を追加していくアプローチがお勧めです。また、定期的にパイプラインの効率と信頼性を評価し、継続的に改善していくことで、より効果的なCI/CD環境を構築できるでしょう。
コメント