AWS CodePipeline、CodeBuild、SAMを用いたGitHub連携でのLambda関数のCI/CDパイプライン構築をしてみた
はじめに
かつまたです。
今回はCode系サービスの学習のため、GitHubと連携したAWS CodePipelineを使用してLambda関数のCI/CDパイプラインを構築してみました。GitHubからソースコードを取得し、CodeBuildでビルド・パッケージ化を行い、CloudFormationでAWS SAMテンプレートをデプロイするまでの一連の流れを自動化します。
構成図
やってみた
前提条件
- アーティファクト用S3バケット作成済み
- GitHubリポジトリに以下のファイルを作成しました。
index.js
exports.handler = async (event) => {
console.log('Event received:', JSON.stringify(event, null, 2));
const response = {
statusCode: 200,
body: JSON.stringify({
message: 'Hello from Lambda CI/CD Pipeline!',
timestamp: new Date().toISOString()
}),
};
return response;
};
buildspec.yml
version: 0.2
phases:
install:
runtime-versions:
nodejs: 20
python: 3.9
pre_build:
commands:
- npm install
- echo "S3 Bucket = $BUCKET_NAME"
build:
commands:
- pip install aws-sam-cli # SAM CLIをインストール
- sam build
- sam package --s3-bucket $BUCKET_NAME --output-template-file packaged-template.yaml
artifacts:
files:
- packaged-template.yaml
- template.yml
discard-paths: no
env:
variables:
BUCKET_NAME: "codepipelinestartertempla-codepipelineartifactsbuc-ehruu2uentoj"
template.yml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
LambdaFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: cicd-demo-function
Handler: index.handler
Runtime: nodejs20.x
MemorySize: 128
Timeout: 10
CodeUri: .
Policies:
- AWSLambdaBasicExecutionRole
Events:
ApiEvent:
Type: Api
Properties:
Path: /hello
Method: get
package.json
{
"name": "lambda-cicd-demo",
"version": "1.0.0",
"description": "Lambda function deployed via CI/CD pipeline",
"main": "index.js",
"author": "",
"license": "MIT"
}
GitHub接続設定
-
ディベロッパー用ツール→設定→接続からGitHubとの接続を作成する。
-
「新しいアプリをインストールする」から自身のGitHubとの接続を作成し、認証する。
IAMロール設定
それぞれのリソースのサービスリンクロールを作成します。
Codebuild用IAMロール
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": [
"arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws/codebuild/lambda-cicd-build",
"arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws/codebuild/lambda-cicd-build:*"
],
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
},
{
"Effect": "Allow",
"Action": [
"codeconnections:UseConnection",
"codeconnections:GetConnection",
"codeconnections:ListConnections",
"codestar-connections:UseConnection",
"codestar-connections:GetConnection",
"codestar-connections:ListConnections"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::codepipeline-ap-northeast-1-*"
],
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetBucketAcl",
"s3:GetBucketLocation"
]
},
{
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::codepipeline-artifacts-bucket-name",
"arn:aws:s3:::codepipeline-artifacts-bucket-name/*"
],
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetBucketAcl",
"s3:GetBucketLocation"
]
},
{
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::lambda-cicd-artifacts-bucket",
"arn:aws:s3:::lambda-cicd-artifacts-bucket/*"
],
"Action": [
"s3:PutObject",
"s3:GetBucketAcl",
"s3:GetBucketLocation"
]
},
{
"Effect": "Allow",
"Action": [
"codebuild:CreateReportGroup",
"codebuild:CreateReport",
"codebuild:UpdateReport",
"codebuild:BatchPutTestCases",
"codebuild:BatchPutCodeCoverages"
],
"Resource": [
"arn:aws:codebuild:ap-northeast-1:123456789012:report-group/lambda-cicd-build-*"
]
}
]
}
CodePipeline用IAMロール
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:Abort*",
"s3:DeleteObject*",
"s3:GetBucket*",
"s3:GetObject*",
"s3:List*",
"s3:PutObject",
"s3:PutObjectLegalHold",
"s3:PutObjectRetention",
"s3:PutObjectTagging",
"s3:PutObjectVersionTagging"
],
"Resource": [
"arn:aws:s3:::codepipeline-artifacts-bucket-name",
"arn:aws:s3:::codepipeline-artifacts-bucket-name/*"
],
"Effect": "Allow"
},
{
"Action": [
"s3:PutObjectAcl",
"s3:PutObjectVersionAcl"
],
"Resource": "arn:aws:s3:::codepipeline-artifacts-bucket-name/*",
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": [
"arn:aws:iam::123456789012:role/CodePipelineSourceActionRole",
"arn:aws:iam::123456789012:role/CodePipelineDeployActionRole"
],
"Effect": "Allow"
},
{
"Action": [
"codebuild:BatchGetBuilds",
"codebuild:StartBuild"
],
"Resource": "arn:aws:codebuild:ap-northeast-1:123456789012:project/lambda-cicd-build",
"Effect": "Allow"
}
]
}
CloudFormation用IAMロール(以下2つのポリシーをアタッチ)
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"cloudformation:*"
],
"Resource": [
"arn:aws:cloudformation:ap-northeast-1:123456789012:stack/lambda-cicd-stack"
],
"Effect": "Allow"
},
{
"Action": "sts:AssumeRole",
"Resource": [
"arn:aws:iam::123456789012:role/CodePipelineDeployRole"
],
"Effect": "Allow"
},
{
"Action": [
"s3:GetBucket*",
"s3:GetObject*",
"s3:List*",
"s3:PutObject",
"s3:PutObjectLegalHold",
"s3:PutObjectRetention",
"s3:PutObjectTagging",
"s3:PutObjectVersionTagging"
],
"Resource": [
"arn:aws:s3:::codepipeline-artifacts-bucket-name",
"arn:aws:s3:::codepipeline-artifacts-bucket-name/*"
],
"Effect": "Allow"
},
{
"Action": [
"s3:PutObjectAcl",
"s3:PutObjectVersionAcl"
],
"Resource": "arn:aws:s3:::codepipeline-artifacts-bucket-name/*",
"Effect": "Allow"
},
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws/codepipeline/DeployToCloudFormationService",
"arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws/codepipeline/DeployToCloudFormationService:*"
],
"Effect": "Allow"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PermissionsForCloudFormation",
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
Codebuild設定
-
CodeBuild→ビルドプロジェクトからCodebuildを作成していきます。
-
先ほど作成したGitHub接続を利用してソースを設定します。
- ソースプロバイダー:GitHub
- リポジトリ:使用するリポジトリのURLを選択
- 環境設定を以下のように設定します。先ほど作成したCodeBuild用IAMロールを利用します。
-
buildspec設定は「buildspecファイルを使用する」とすることでGitHub上のbuildspecファイルが利用されます。
-
アーティファクト設定は以下のように設定します。
- S3バケット名:作成済みのアーティファクト用S3バケット名
- パス:build/
- 上記設定を確認し、Codebuildを作成します。
CodePipeline設定
-
CodePipeline→パイプラインからCodePipelineを作成します。本ブログでは作成オプションは「カスタムパイプラインを構築する」を選択します。
-
作成したロールを選択します。
-
ソースステージ設定では以下のように設定します。
ソースプロバイダー:GitHub接続→利用するリポジトリ選択
出力アーティファクト:Codebuildのデフォルト
- ビルドステージ設定では以下のように設定します。
- プロバイダー:その他のビルドプロバイダー→AWS Codebuild
- 入力アーティファクト:SourceArtifact(ソースステージの出力アーティファクト)
-
テストステージはスキップします。
-
デプロイステージ設定では以下の通り設定します。
- デプロイプロバイダー:AWS CloudFormation
- 入力アーティファクト:BuildArtifact
- アクションモード:スタックを作成または更新する
- テンプレート
- アーティファクト名:BuildArtifact
- ファイル名:packaged-template.yml
- 機能:全て選択
- ロール名:作成したCloudFormation用ロール
- 設定を確認し、CodePipelineを作成します。
動作確認
-
CodePipeline作成後、パイプラインを実行します。
-
パイプライン実行成功後、CloudFormationスタックやLambdaのデプロイを確認できました。
おわりに
ご覧いただきありがとうございました。上記内容でGitHub連携のCodePipeline、CodeBuild、CloudFormation(SAM)を用いたCI/CDパイプラインの構築を実施することができました。
CodePipelineの各ステージの詳細設定についてはまだまだ理解不足であると感じたので学習を継続していきたいと思います。
アノテーション株式会社について
アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。当社は様々な職種でメンバーを募集しています。「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイトをぜひご覧ください。