2
3

More than 3 years have passed since last update.

IAMをゼロから設定し、Code Buildのビルドプロジェクトを作成・ビルド実行までやってみた(Management Console版)

Last updated at Posted at 2021-09-01

はじめに

GitHub Actions、CircleCiを使ったCIは構築した事があったが、Code BuildでのCIはやった事がなかったのでやってみた
その際の備忘録を残す

※前提条件として既にCode Commitにbuild対象のソースコードがある状態からスタートした
※ビルドするものはGoのLambda関数

buildspec.ymlや、GitHub Actionsでのビルドは以下のリポジトリを参照

Code Buildのビルドプロジェクトを作成する

Management Consoleからビルドプロジェクトを作成する

以下の画像のように設定できる

1 2 3 4
image.png image.png image.png image.png

※上記の画像では、イメージ(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 - オプショナルとは以下のリストの部分
image.png
image.png

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によって自動的に作成されたもの)
image.png

S3

ビルドプロジェクトを作成する際に、ソースプロバイダやアーティファクトなどでS3を設定できるので最低限S3のアクセス権限がないとビルドプロジェクト作成がAccess Deniedになる
image.png

{
    "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全体としては以下のようになる

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される
image.png

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を見るために必要。

image.png

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を作成した時にブロックパブリックアクセス (バケット設定)パブリックアクセスをすべて ブロックがオフになっている状態を、オンにする修正するのに必要な権限
image.png

{
    "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: 

image.png

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3