はじめに
GitHub Actions、CircleCiを使ったCIは構築した事があったが、Code BuildでのCIはやった事がなかったのでやってみた
その際の備忘録を残す
※前提条件として既にCode Commitにbuild対象のソースコードがある状態からスタートした
※ビルドするものはGoのLambda関数
buildspec.ymlや、GitHub Actionsでのビルドは以下のリポジトリを参照
Code Buildのビルドプロジェクトを作成する
Management Consoleからビルドプロジェクトを作成する
以下の画像のように設定できる
1 | 2 | 3 | 4 |
---|---|---|---|
※上記の画像では、イメージ
(docker image)はaws/codebuild/standard:4.0
になっているが、作成後にGoの1.16をruntime versionに指定できるのはaws/codebuild/standard:5.0
である事が後かは判明したのでそれに修正した
※「ソース」でブランチ(ビルドするコードを含むブランチを選択します。)
を設定しているが、これはstart buildをした時にオプションで何も指定されなかった時にどのソースバージョンでbuildするか?を決められるようにするために設定しているもので、start build時に指定すればこの設定は上書きされる
CodeCommit の場合、ビルドするソースコードのバージョンに対応するコミット ID。sourceVersion が指定されなければ、デフォルトブランチの HEAD コミット ID が使用されます。(sourceVersion にタグ名は指定できません。しかし、タグのコミット ID は指定できます。)
・参考:ビルドの実行 (AWS CLI)
ビルドプロジェクトを作成するために必要なIAM
上記のビルドプロジェクトを作成する上で必要になる権限はいくつかある
※Code Buildのビルドプロジェクトは、他のAWSサービスとの連携が結構あるのでその分必要な権限も多い
- Code Build:言わずもがな
- Code Commit:今回はソースプロバイダをCode Commitにするので必要
- IAM:ビルドプロジェクトへサービスロールをアタッチしたり、そのサービスロールを作成するために必要
- S3:アーティファクトの保存先のBucket作成、保存されたものへアクセスするために必要
・参考:AWS CodeBuild のアクセス許可に関するリファレンス
Code Build
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"codebuild:BatchGetProjects",
"codebuild:CreateProject"
],
"Resource": "arn:aws:codebuild:ap-northeast-1:xxxxxxxxxxxx:project/go-build-console"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"codebuild:ListCuratedEnvironmentImages",
"codebuild:ListProjects"
],
"Resource": "*"
}
]
}
action名 | 説明 |
---|---|
codebuild:BatchGetProjects | 1つ以上のビルドプロジェクトに関する情報を取得する権限。単純に自分で作成したビルドプロジェクトの内容を確認するために必要。 |
codebuild:CreateProject | ビルドプロジェクトを作成する権限。 |
codebuild:ListCuratedEnvironmentImages | AWSCodeBuildのコンテナ(Docker)イメージに関する情報を取得する権限。これないと環境イメージ の選択とかができない。 |
codebuild:ListProjects | ビルドプロジェクト名の一覧をリストを取得する権限。Code Buildのビルドプロジェクト メニューを選択して表示されるビルドプロジェクト一覧を見れるようにするに必要。 |
Code Commit
ソース
の項目を設定する上で必要になる
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"codecommit:GetCommit",
"codecommit:GetCommitHistory",
"codecommit:GetReferences"
],
"Resource": "arn:aws:codecommit:ap-northeast-1:xxxxxxxxxxxx:go"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "codecommit:ListRepositories",
"Resource": "*"
}
]
}
action名 | 説明 |
---|---|
codecommit:GetCommit | コミットメッセージやコミッター情報などのコミットに関する情報を取得する権限。ソース のコミット ID - オプショナル の部分を設定できるようにするために必要。 |
codecommit:GetCommitHistory | リポジトリ内のコミットの履歴に関する情報を取得する権限。ソース のコミット ID - オプショナル の部分を設定できるようにするために必要。 |
codecommit:GetReferences | CodeCommitリポジトリ内の参照に関する詳細を取得する権限。ソース のソースバージョン を表示させるために必要。 |
codecommit:ListRepositories | AWSアカウントの現在のリージョンにあるAWSCodeCommitリポジトリに関する情報を一覧表示する権限。ソース のリポジトリ の選択リストを表示させるための必要。 |
※ソース
とは以下の画像の部分で、コミット ID - オプショナル
とは以下のリストの部分
IAM
ビルドプロジェクトにアタッチしたサービスロールに対し、ビルドプロジェクトが必要になる権限(アーティファクトの保存先であるS3の権限、ビルドのlogを記録するためのCloud Watch Logsの権限、ビルド実行後のレポートを出力するためのCode Buildの権限)などのポリシーを追加したりそのポリシーのバージョンを操作するための権限
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"iam:CreatePolicy",
"iam:PassRole",
"iam:CreateRole",
"iam:AttachRolePolicy",
"iam:CreatePolicyVersion",
"iam:DeletePolicyVersion"
],
"Resource": [
"arn:aws:iam::xxxxxxxxxxxx:role/go-build-console",
"arn:aws:iam::xxxxxxxxxxxx:policy/*"
]
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"iam:ListPolicies",
"iam:ListRoles"
],
"Resource": "*"
}
]
}
action名 | 説明 |
---|---|
iam:CreatePolicy | 新しい管理ポリシーを作成する権限。AWS側で自動的にポリシー作成できるようにするために必要。 |
iam:PassRole | サービスに役割を渡す権限。Code Buildのビルドプロジェクトにサービスロールを指定できるようにするのに必要。 |
iam:CreateRole | 新しいロールを作成する権限。新規でロールを作成するのに必要で、サービスロールとしてアタッチするロール作成で必要になった。 |
iam:AttachRolePolicy | 指定されたIAMロールに管理ポリシーをアタッチする権限。AWS側で自動的にロールにポリシーをアタッチできるようにするのに必要。 |
iam:CreatePolicyVersion | 指定された管理ポリシーの新しいバージョンを作成する権限。AWS側で自動的にポリシーを作成できるようにするために必要。 |
iam:DeletePolicyVersion | 指定された管理対象ポリシーからバージョンを削除する権限。AWS側で自動的にポリシーを変更できるようにするために必要。 |
iam:ListPolicies | すべての管理対象ポリシーを一覧表示する権限。AWS側で自動的にポリシーを変更できるようにするために必要。 |
iam:ListRoles | 指定されたパスプレフィックスを持つIAMロールを一覧表示する権限。環境 のサービスロール にロールを一覧表示させるのに必要。 |
※AWS側で自動的に
→AWSが勝手にやるが、その権限はログインユーザの権限で動くのでログインユーザにそれを行う権限を付与させる必要がある
※Management Consoleからビルドプロジェクトを作成すると、自動的にサービスロールにポリシーが新規でアタッチされる(go-build-console
というロールは自分で作成したものだが、CodeBuildBasePolicy-go-build-console-ap-northeast-1
というポリシーはAWSによって自動的に作成されたもの)
S3
ビルドプロジェクトを作成する際に、ソースプロバイダやアーティファクトなどでS3を設定できるので最低限S3のアクセス権限がないとビルドプロジェクト作成がAccess Denied
になる
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "s3:CreateBucket",
"Resource": "arn:aws:s3:::go-build-console"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*"
}
]
}
action名 | 説明 |
---|---|
s3:CreateBucket | 新しいバケットを作成する権限。アーティファクト で保存先(タイプ )にS3を選択した際に、バケット名 を指定するがそのBucketを作成するのに必要。 |
s3:ListAllMyBuckets | リクエストの認証された送信者が所有するすべてのバケットを一覧表示する権限。アーティファクト で保存先(タイプ )にS3を選択した際のバケット名 を指定際に表示されるBucket一覧を表示させるために必要。 |
buildspecを作成しビルドを実行する
buildspecを実装する
作業に必要なIAMはbuildspecを実装しビルドを実行するのに必要なIAMの項を参照
SSHでgit cloneできるようにする
以下の参考のサイトにある通り
・参考:Step ステップ 3: Linux、macOS、または Unix で認証情報を設定する
・参考:複数のAWSアカウントを利用する場合のCodeCommit SSHパスの設定方法
Code Buildのyamlの書き方のルール
正直全部は分からないので、ひとまずCodeBuild のビルド仕様に関するリファレンスを見ながら手さぐりで書いてみた
GoのLambdaのbuild(zipファイルを作成する)のyaml
Goのruntimeの指定は以下のようにできる
install:
runtime-versions:
golang: 1.16
後はLinux環境でのGoのLambdaのbuild手順(.zip ファイルアーカイブを使用して Go Lambda 関数をデプロイする)通りにコマンドを実行すればよく、buildspec.yml全体としては以下のようになる
version: 0.2
phases:
install:
runtime-versions:
golang: 1.16
pre_build:
commands:
- echo "go version"
- go version
- echo "go get aws lambda library"
- go get github.com/aws/aws-lambda-go/lambda
build:
commands:
- echo "go build"
- GOOS=linux go build -o main lambda.go
post_build:
commands:
- echo "create zip"
- zip main.zip main config.yaml
artifacts:
files:
- main.zip
・参考:CodeBuild の Amazon ECR サンプル Go プロジェクトのファイル
・参考:使用可能なランタイム Linux イメージのランタイム
・参考:ランタイムバージョン
ビルドを実行する
buildが成功すると以下のようにS3にビルド成果物がs3:::go-build-console/artifact/
以下にuploadされる
buildspecを実装しビルドを実行するのに必要なIAM
上記のビルドプロジェクトを作成するために必要なIAMで付与した権限以外に以下のactionを実行する権限を追加で付与する
(Code Commitについてはbuildspecが見れないと困るので追加で権限付与をしている)
Code Build
action名 | 説明 |
---|---|
codebuild:ListBuildsForProject | 指定されたビルドプロジェクトのビルドIDのリストを取得する権限。ビルド履歴を閲覧できるようにするのに必要。 |
codebuild:StartBuild | ビルドの実行を開始する権限。 |
codebuild:UpdateProject | 既存のビルドプロジェクトの設定を変更する権限。 |
codebuild:BatchGetBuilds | 1つ以上のビルドに関する情報を取得する権限。ビルド履歴のビルド1つ1つの詳細を確認できるようにするのに必要。 |
※"Resource"
の設定は、ビルドプロジェクトを作成するために必要なIAMのCode Buildの項と同じで、"Resource": "arn:aws:codebuild:ap-northeast-1:xxxxxxxxxxxx:project/go-build-console"
Code Commit
action名 | 説明 |
---|---|
codecommit:GetRepository | AWSCodeCommitリポジトリに関する情報を取得する権限。 |
codecommit:GetTree | AWSCodeCommitコンソールからAWSCodeCommitリポジトリ内の指定されたツリーのコンテンツを表示する権限。リポジトリのフォルダ(階層構造)を表示させるのに必要。 |
codecommit:GetObjectIdentifier | ブロブ、ツリーを解決する権限。 |
codecommit:GetBlob | AWSCodeCommitコンソールからAWSCodeCommitリポジトリ内の個々のファイルのエンコードされたコンテンツを表示する権限。ファイルの中身を見れるようにするのに必要。 |
codecommit:GitPush | ローカルリポジトリからAWSCodeCommitリポジトリに情報をプッシュする権限。 |
※"Resource"
の設定は、ビルドプロジェクトを作成するために必要なIAMのCode Commitの項と同じで、"Resource": "arn:aws:codecommit:ap-northeast-1:xxxxxxxxxxxx:go"
S3
action名 | 説明 |
---|---|
s3:ListBucket | Amazon S3バケット内のオブジェクトの一部またはすべてを一覧表示する権限。build成果物を確認するために必要。 |
※"Resource"
の設定は、ビルドプロジェクトを作成するために必要なIAMのS3のCreateBucket
と同じで、"Resource": "arn:aws:s3:::go-build-console"
Cloud Watch Logs
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "logs:GetLogEvents",
"Resource": "arn:aws:logs:ap-northeast-1:xxxxxxxxxxxx:log-group:/aws/codebuild/go-build-console:log-stream:*"
}
]
}
action名 | 説明 |
---|---|
logs:GetLogEvents | 指定されたログストリームからログイベントを取得する権限。ビルド結果のlogを見るために必要。 |
IAM
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "iam:UploadSSHPublicKey",
"Resource": "arn:aws:iam::xxxxxxxxxxxx:user/codebuild-only"
}
]
}
action名 | 説明 |
---|---|
iam:UploadSSHPublicKey | SSH公開鍵をアップロードし、それを指定されたIAMユーザーに関連付ける権限。gitの操作をSSHで行うのに必要。 |
おまけ
S3のIAMで追加した方がいいと思われるもの
以下はBucketを作成した時にブロックパブリックアクセス (バケット設定)
のパブリックアクセスをすべて ブロック
がオフになっている状態を、オンにする修正するのに必要な権限
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:GetBucketPublicAccessBlock",
"s3:PutBucketPublicAccessBlock"
],
"Resource": "arn:aws:s3:::go-build-console"
}
]
}
・参考:Amazon S3 ストレージへのパブリックアクセスのブロック Permissions
Code Buildのlog
[Container] 2021/09/01 13:01:30 Waiting for agent ping
[Container] 2021/09/01 13:01:33 Waiting for DOWNLOAD_SOURCE
[Container] 2021/09/01 13:01:38 Phase is DOWNLOAD_SOURCE
[Container] 2021/09/01 13:01:38 CODEBUILD_SRC_DIR=/codebuild/output/src575922894/src/git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/go
[Container] 2021/09/01 13:01:38 YAML location is /codebuild/output/src575922894/src/git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/go/.aws/buildspec.yml
[Container] 2021/09/01 13:01:38 No commands found for phase name: install
[Container] 2021/09/01 13:01:38 Processing environment variables
[Container] 2021/09/01 13:01:38 Selecting 'golang' runtime version '1.16' based on manual selections...
[Container] 2021/09/01 13:01:38 Running command echo "Installing Go version 1.16 ..."
Installing Go version 1.16 ...
[Container] 2021/09/01 13:01:38 Running command goenv global $GOLANG_16_VERSION
[Container] 2021/09/01 13:01:38 Moving to directory /codebuild/output/src575922894/src/git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/go
[Container] 2021/09/01 13:01:39 Registering with agent
[Container] 2021/09/01 13:01:39 Phases found in YAML: 4
[Container] 2021/09/01 13:01:39 INSTALL: 0 commands
[Container] 2021/09/01 13:01:39 PRE_BUILD: 4 commands
[Container] 2021/09/01 13:01:39 BUILD: 2 commands
[Container] 2021/09/01 13:01:39 POST_BUILD: 2 commands
[Container] 2021/09/01 13:01:39 Phase complete: DOWNLOAD_SOURCE State: SUCCEEDED
[Container] 2021/09/01 13:01:39 Phase context status code: Message:
[Container] 2021/09/01 13:01:39 Entering phase INSTALL
[Container] 2021/09/01 13:01:39 Phase complete: INSTALL State: SUCCEEDED
[Container] 2021/09/01 13:01:39 Phase context status code: Message:
[Container] 2021/09/01 13:01:39 Entering phase PRE_BUILD
[Container] 2021/09/01 13:01:39 Running command echo "go version"
go version
[Container] 2021/09/01 13:01:39 Running command go version
go version go1.16.4 linux/amd64
[Container] 2021/09/01 13:01:40 Running command echo "go get aws lambda library"
go get aws lambda library
[Container] 2021/09/01 13:01:40 Running command go get github.com/aws/aws-lambda-go/lambda
go: downloading github.com/aws/aws-lambda-go v1.26.0
[Container] 2021/09/01 13:01:50 Phase complete: PRE_BUILD State: SUCCEEDED
[Container] 2021/09/01 13:01:50 Phase context status code: Message:
[Container] 2021/09/01 13:01:50 Entering phase BUILD
[Container] 2021/09/01 13:01:50 Running command echo "go build"
go build
[Container] 2021/09/01 13:01:50 Running command GOOS=linux go build -o main lambda.go
go: downloading github.com/jinzhu/configor v1.2.1
go: downloading github.com/slack-go/slack v0.9.4
go: downloading github.com/BurntSushi/toml v0.3.1
go: downloading gopkg.in/yaml.v2 v2.2.3
go: downloading github.com/pkg/errors v0.8.0
go: downloading github.com/gorilla/websocket v1.4.2
[Container] 2021/09/01 13:01:56 Phase complete: BUILD State: SUCCEEDED
[Container] 2021/09/01 13:01:56 Phase context status code: Message:
[Container] 2021/09/01 13:01:56 Entering phase POST_BUILD
[Container] 2021/09/01 13:01:56 Running command echo "create zip"
create zip
[Container] 2021/09/01 13:01:56 Running command zip main.zip main config.yaml
adding: main (deflated 50%)
adding: config.yaml (deflated 71%)
[Container] 2021/09/01 13:01:57 Phase complete: POST_BUILD State: SUCCEEDED
[Container] 2021/09/01 13:01:57 Phase context status code: Message:
[Container] 2021/09/01 13:01:57 Expanding base directory path: .
[Container] 2021/09/01 13:01:57 Assembling file list
[Container] 2021/09/01 13:01:57 Expanding .
[Container] 2021/09/01 13:01:57 Expanding file paths for base directory .
[Container] 2021/09/01 13:01:57 Assembling file list
[Container] 2021/09/01 13:01:57 Expanding main.zip
[Container] 2021/09/01 13:01:57 Found 1 file(s)
[Container] 2021/09/01 13:01:57 Phase complete: UPLOAD_ARTIFACTS State: SUCCEEDED
[Container] 2021/09/01 13:01:57 Phase context status code: Message: