AWS CodeBuildとJenkinsの連携
TL;DR
AWS CodeBuildとJenkinsを連携させると、これまでJenkins Agentで実行していたビルド処理をAWS CodeBuildに置き換えることができます。以下のメリットがあります。
- AWS CodeBuildは無限に*1スケールするので、ビルドキューの待ち行列がなくなる
- ビルド単位で課金されるので、Jenkins AgentのEC2インスタンスを待機させておくコストが不要になる
- コンテナでビルド処理が実行されるので、ビルドに必要なOSやミドルウェアを管理する手間がなくなる
- JenkinsのUIやユーザ管理をそのまま使い続けられるので導入しやすい
AWS CodeBuildとJenkinsを連携させるには公式の AWS CodeBuild Plugin を利用します。
AWS CodeBuildとJenkinsの連携はGitHubだけでなくGitBucketやGitLabでも利用できます。
Getting Started
ここではGitHub→Jenkins→AWS CodeBuildを連携させる例を説明します。ビルドのトリガーは下図のようになります。
+----------------------------------+ | 開発者 +----------------------------------+ ↓ git push +----------------------------------+ | GitHub +----------------------------------+ ↓ webhook +----------------------------------+ | Jenkins +----------------------------------+ ↓ ビルド実行 +----------------------------------+ | AWS CodeBuild +----------------------------------+
GitHubの設定
Jenkinsfile
という名前で下記のファイルを作成します。
node { stage('codebuild') { awsCodeBuild( projectName: 'sandbox', region: 'ap-northeast-1', sourceControlType: 'project', sourceVersion: env.BRANCH_NAME, // CodeBuildにブランチ名を環境変数で渡すため envVariables: "[{BRANCH_NAME,${env.BRANCH_NAME}}]", ) } }
buildspec.yml
という名前で下記のファイルを作成します。
version: 0.2 phases: build: commands: - echo "Current branch is $BRANCH_NAME."
Jenkinsの設定
AWS CodeBuild Pluginをインストールしておきます。
Multibranch Pipelineジョブを作成し、先ほど作成したGitHubのリポジトリをビルドするように設定します。詳しい手順は https://go.cloudbees.com/docs/cloudbees-documentation/cje-user-guide/index.html#github-branch-source を参照してください。
JenkinsからAWS CodeBuildを操作できるようにするため、Jenkinsを実行しているEC2インスタンスにIAMロールを付与します。IAMロールを利用できない場合は代わりにIAMユーザを作成し、アクセスキーとシークレットキーをJenkinsの認証情報に登録しておきます。
IAMロールにアタッチするポリシーは https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/jenkins-plugin.html を参照してください。とりあえず下記のポリシーをアタッチすれば動きますが、本来はもう少し絞った方がよいでしょう。
AWS CodeBuildの設定
マネジメントコンソールからAWS CodeBuildを開き、新しいプロジェクトを作成します。
- ソースプロバイダ: GitHub
- リポジトリ: 先ほど作成したGitHubのリポジトリを指定します
- Webhook: オフ
- 環境イメージ: AWS CodeBuild によって管理されたイメージの使用
- ランタイム: Java
- ランタイムバージョン:
aws/codebuild/java:openjdk-8
- ビルド仕様: ソースコードのルートディレクトリの buildspec.yml を使用
- サービスロール: アカウントでサービスロールを作成
ここではJavaのアプリケーションをビルドする設定としましたが、他の言語も利用できます。
新しいプロジェクトを作成したら、ビルドの開始 をクリックしてビルドが成功するか確認しておきます。
動作確認
GitHubに新しいコミットをpushします。まず、Jenkinsで新しいビルドが実行されることを確認します。ビルドが実行されない場合はJenkinsの設定からログを確認してみてください。Webhookやアクセストークンの設定に問題があることが多いです。
次に、AWS CodeBuildで新しいビルドが実行されることを確認します。ビルドが実行されない場合はビルドログにエラーメッセージが出ていると思います。IAMロールの権限不足やプロジェクト名の誤りなどが考えられます。
ビルドした成果物のS3へのアップロード
AWS CodeBuildにはビルドした成果物をS3バケットにアップロードする機能があります。S3バケットからEC2インスタンスにアプリをリリースしている場合に有用です。
まず、成果物をアップロードするためのS3バケットを作成します。ここではバケット名を s3-release
とします。
AWS CodeBuildのプロジェクトで以下を設定します。
buildspec.yml
に以下を書きます。
version: 0.2 phases: build: commands: - echo "Current branch is $BRANCH_NAME." > result.txt artifacts: files: - result.txt
AWS CodeBuildでビルドを実行してみましょう。S3バケットに result.txt
という名前のファイルが配置されていれば成功です。
S3パスの動的な指定
ブランチ名に応じてS3バケットのパスを変えたいといった場合は、Jenkinsfileの artifactPathOverride
を利用してパスを指定します。
// Jenkinsfile node { stage('codebuild') { awsCodeBuild( projectName: 'sandbox', region: 'ap-northeast-1', sourceControlType: 'project', sourceVersion: env.BRANCH_NAME, envVariables: "[{BRANCH_NAME,${env.BRANCH_NAME}}]", // S3に成果物をアップロードする artifactLocationOverride: 's3-release', artifactNameOverride: '/', artifactPathOverride: "/releases/${env.BRANCH_NAME}/", artifactPackagingOverride: 'NONE', artifactTypeOverride: 'S3', ) } }
Gitリポジトリにコミットをpushし、Jenkins経由でビルドを実行してみましょう。master
ブランチをpushした場合は /releases/master/result.txt
というファイルが配置されているはずです。
GitHub以外のリポジトリとの連携
GitBucket
GitBucketはGitHub Enterpriseとして振る舞うことができるので、特別な対応は不要です。Jenkinsの設定ではGitHubをGitBucketに読み替えて設定してください。AWS CodeBuildの設定ではGitHub Enterpriseを指定します。詳しくは以下を参考にしてください。
- Setup Jenkins Multibranch Pipeline and Organization · gitbucket/gitbucket Wiki · GitHub
- AWS CodeBuildとGitBucketの連携 - GeekFactory
GitLab
JenkinsとGitLabを連携させるにはJenkins GitLab Pluginが必要です。詳しい手順は JenkinsとGitLabを連携する方法 を参照してください。
(2018-06-28追記)GitBucketと同様の方法で、AWS CodeBuildがGitLabからソースコードを取得できるようになります。
以下は古い内容です。
AWS CodeBuildはGitLabに対応していないため、S3経由でソースコードを渡す必要があります。
+----------------------------------+ | 開発者 +----------------------------------+ ↓ git push +----------------------------------+ | GitLab +----------------------------------+ ↓ webhook +----------------------------------+ | Jenkins (Jenkins GitLab Plugin) +----------------------------------+ ↓ ソースコードを保存 +----------------------------------+ | S3バケット +----------------------------------+ ↓ ソースコードをビルド +----------------------------------+ | AWS CodeBuild +----------------------------------+
まず、ソースコードを配置するためのS3バケットを作成します。オブジェクトバージョニングを有効にしておきます(有効にしないとJenkins AWS CodeBuild Pluginがエラーになります)。
AWS CodeBuildのプロジェクトの設定でS3からソースコードを取得するようにします。
Jenkinsfileでは sourceControlType
を jenkins
に設定します。これにより、Jenkinsが取得したソースコードがS3バケットに配置されるようになります。
// Jenkinsfile node { stage('codebuild') { awsCodeBuild( projectName: 'sandbox', region: 'ap-northeast-1', sourceControlType: 'jenkins', sourceVersion: env.BRANCH_NAME, envVariables: "[{BRANCH_NAME,${env.BRANCH_NAME}}]", ) } }
Jenkinsのビルドログを開き、下記のようなS3バケットへのアップロードのログが表示されていれば成功です。
[Pipeline] awsCodeBuild [AWS CodeBuild Plugin] Uploading code to S3 at location sandbox/jenkins. MD5 checksum is ... [AWS CodeBuild Plugin] S3 object version id for uploaded source is ... [AWS CodeBuild Plugin] Starting build with > project name: jenkins-docker > source version: ... [AWS CodeBuild Plugin] Build id: jenkins:895c9eba-b455-4f70-a83a-babe3d50fa39 [AWS CodeBuild Plugin] CodeBuild dashboard: https://ap-northeast-1.console.aws.amazon.com/codebuild/home?region=ap-northeast-1#builds/jenkins:... [AWS CodeBuild Plugin] CloudWatch dashboard: https://console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1#logEvent:group=/aws/codebuild/jenkins;... [AWS CodeBuild Plugin] 2018/04/12 03:33:00 Waiting for agent ping [AWS CodeBuild Plugin] 2018/04/12 03:33:00 Waiting for DOWNLOAD_SOURCE [AWS CodeBuild Plugin] 2018/04/12 03:33:08 Phase is DOWNLOAD_SOURCE [AWS CodeBuild Plugin] 2018/04/12 03:33:08 CODEBUILD_SRC_DIR=/codebuild/output/src896775218/src [AWS CodeBuild Plugin] 2018/04/12 03:33:08 YAML location is /codebuild/output/src896775218/src/buildspec.yml [AWS CodeBuild Plugin] 2018/04/12 03:33:08 Processing environment variables [AWS CodeBuild Plugin] 2018/04/12 03:33:08 Moving to directory /codebuild/output/src896775218/src [AWS CodeBuild Plugin] 2018/04/12 03:33:08 Registering with agent [AWS CodeBuild Plugin] 2018/04/12 03:33:08 Phases found in YAML: 1 [AWS CodeBuild Plugin] 2018/04/12 03:33:08 BUILD: 1 commands [AWS CodeBuild Plugin] 2018/04/12 03:33:08 Phase complete: DOWNLOAD_SOURCE Success: true
まとめ
ビルドキューの待ち行列やJenkins Agentインスタンスのメンテナンスで疲弊している場合はAWS CodeBuildを試してみましょう。
*1:デフォルトでは同時実行数は20に制限されています。