0
1

More than 1 year has passed since last update.

【AWS CodeBuild】TerraformでCodeBuild BuildProjectを作成してみた【Terraform】

Posted at

BuildProjectを Terraform で構築する

試したバージョン

Name Version
terraform 1.1.5
aws 4.0

必要リソース

CodeBuild でビルドを行う際に作成が必要となるAWSリソースは以下の通り

  • CodeBuild ビルドプロジェクト
  • S3 バケット or CodeCommit リポジトリ
  • IAM ロール
  • (オプション)CloudWatchLogs ロググループ,ログストリーム

手順

公式の手順を参考にterraform tfファイルを作成していきます
AWS CodeBuild - 開始方法

1. ファイル準備

ビルド対象のソースファイルを作成します
ディレクトリ構成が以下の通りになるよう、公式手順を見ながら作成してください

$ tree tutorial/
tutorial/
├── buildspec.yaml
├── pom.xml
└── src
    ├── main
    │   └── java
    │       └── MessageUtil.java
    └── test
        └── java
            └── TestMessageUtil.java

5 directories, 4 files

2. S3 バケット作成

ソースファイルの読み込み元として利用するインプット用バケット、
ビルド完了したアーティファクトの保管先となるアウトプット用バケットの2つを作成します

input,outputを同じバケットにすることもできますが、分かりやすくするために2つ作成します

input,output用バケットはそれぞれ1つずつだけでいいと思うので、こちらはmoduleには含めず
resourceで宣言します

s3.tf
# input用バケット
resource "aws_s3_bucket" "input" {
  bucket = "tutorial-codebuild-input"
}

# output用バケット
resource "aws_s3_bucket" "output" {
  bucket = "tutorial-codebuild-output"
}

3. IAMロール作成

ビルドプロジェクトがビルドする際に利用するIAMロールを作成します

IAMポリシーに関しては、ビルドプロジェクトの仕様によって付与する権限が大幅に変わるため、
自力で作成すると権限の過不足が発生しやすいと思います
コンソールで作成すると、IAMロールを自動で作成/権限付与を行ってくれるので、
この点ではTerraformだと不便、、

一応、IAMロールに必要な権限は、以下の通りです

  • S3 バケットに対するアクセス権限
    • inputバケットへの読み取り権限
    • outputバケットへの書き込み権限
  • CloudWatchLogに対するアクセス権限
    • ロググループ作成権限
    • ログストリーム作成権限

tfファイル

iam.tf
# IAM Role

resource "aws_iam_role" "codebuild_iam_role" {
  name = "CodeBuildServiceRole"
  assume_role_policy = data.aws_iam_policy_document.codebuild_assume_role_policy.json
}

# IAM Policy Document

data "aws_iam_policy_document" "codebuild_assume_role_policy" {
  statement {
    effect = "Allow"
    actions = ["sts:AssumeRole"]

    principals {
      type = "Service"
      identifiers = ["codebuild.amazonaws.com"]
    }
  }
}

# IAM Policy

resource "aws_iam_policy" "codebuild_base_policy" {
  name = "CodeBuildBasePolicy"
  policy = file("./codebuild_base_policy.json")
}

resource "aws_iam_policy" "codebuild_ro_policy" {
  name = "CodeBuildReadOnlyPolicy"
  policy = file("./codebuild_ro_policy.json")
}

# Policy Attachment

resource "aws_iam_role_policy_attachment" "codebuild_policy_attachment01" {
  role = aws_iam_role.codebuild_iam_role.name
  policy_arn = aws_iam_policy.codebuild_base_policy.arn
}

resource "aws_iam_role_policy_attachment" "codebuild_policy_attachment02" {
  role = aws_iam_role.codebuild_iam_role.name
  policy_arn = aws_iam_policy.codebuild_ro_policy.arn
}

IAMロールを一つと、ポリシーを2つ作成し、それぞれアタッチメントで関連付けを行っています

ポリシーのJSONは以下の通りです]
<your aws project id> はご自身のAWS ProjectIDに置き換えてください
input用、output用bucket名も、それぞれご自身が作成したものに合わせてください

codebuild_base_policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Resource": [
        "*"
      ],
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ]
    },
    {
      "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:::tutorial-codebuild-output",
        "arn:aws:s3:::tutorial-codebuild-output/*"
      ],
      "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:<your aws project id>:report-group/*"
      ]
    }
  ]
}
  • CloudWatchへの書き込み権限
  • CodePipelineへの権限(多分今回は不要)
  • Output用バケットへの書き込み権限
  • codebuildレポートへの買い込み権限

を付与していますね
もう一つ、ReadOnlyは以下の通りです

codebuild_ro_policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion"
      ],
      "Resource": [
        "arn:aws:s3:::tutorial-codebuild-input/MessageUtil.zip",
        "arn:aws:s3:::tutorial-codebuild-input/MessageUtil.zip/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketAcl",
        "s3:GetBucketLocation"
      ],
      "Resource": [
        "arn:aws:s3:::tutorial-codebuild-input"
      ]
    }
  ]
}
  • Input用のバケットに対してGetBucket権限等
  • Inputバケット内のソースZipファイルに対してGetObject権限等

だけ付与しています

ちなみに、このポリシーどうやって作ったかというと、
コンソールで試しに作ってみたときに自動作成されたロールのポリシーをまねして作りました(本末転倒)

4. Build Project 作成

buildproject本体をterraformで作っていきます

codebuild.tf
resource "aws_codebuild_project" "build_project01" {
  name = "build-project01"

  service_role  = aws_iam_role.codebuild_iam_role.arn

  source {
    type = "S3"
    location = "tutorial-codebuild-input/MessageUtil.zip"
  }

  environment {
    compute_type = "BUILD_GENERAL1_SMALL"
    image = "aws/codebuild/amazonlinux2-x86_64-standard:3.0"
    type = "LINUX_CONTAINER"
  }

  artifacts {
    type = "S3"
    location = "tutorial-codebuild-output"
  }

  logs_config {
    cloudwatch_logs {
      group_name = "/aws/codebuild/build-project01"
      stream_name = "build-log"
    }
  }
}

大きく分けて source, artifact, environmentの3つの項目を詳しく設定します

  • name : ビルドプロジェクトの名前を付けます
  • service_role : さっき作ったIAMのarnを指定します
  • source : input sourceに関する設定です
    • type : S3, CODECOMMIT, GITHUB などから選べます 今回はS3です
    • location : ↑で指定したソースの場所を指定します S3の場合はバケット名/ソースzipファイル とします
  • artifact : output artifactに関する設定です
    • type : source 同様 output先のタイプを指定します outputはS3, CODEPIPELINE, NO_ARTIFACTSが指定できます
    • location : output先の場所を指定します 今回はさっき作ったS3バケットです
  • environment : ビルド処理を行うマシンに関する設定です
    • compute_type : マシンのスペックです Amazon Linuxを利用する場合、GENERAL1_SMALLしか選べないようです
    • image : マシンのイメージです 今回はaws/codebuild/amazonlinux2-x86_64-standard:3.0にしました
    • type : Linux以外にもWindowsマシンが選べたりします
  • logs_config : CloudWatch Logsへのログ書き込みに関する設定です オプションの項目です
    • group_name : ロググループ名を指定します
    • stream_name : ログストリーム名を指定します
    • status : ログの書き込みをやめたいときは、statusを追加して値をDISABLEDにします

作成

$ terraform plan$ terraform apply
で作成します
問題なければビルドプロジェクトが作成されます

ソースファイル圧縮&アップロード

# カレントディレクトリ確認
$ ls
buildspec.yaml  pom.xml  src

# ソールファイル群をzip圧縮します
$ zip MessageUtil.zip *

# s3のインプット用バケットにアップロードします
$ aws s3 cp MessageUtil.zip s3://tutorial-codebuild-input
upload: ./MessageUtil.zip to s3://tutorial-codebuild-input/MessageUtil.zip

ソースのアップが完了したら、
作成されたビルドプロジェクトの詳細ページにアクセスして、ビルドも実行してみましょう
問題なくartifactがoutput用バケットに作成されていればこのチュートリアルは完了です

感想

CodeBuildのBuildProjectと、それに関連するリソースをterraformで作ってみました

BuildProjectのリソースを作成するためにIAMロールの指定が必須なのですが、
このIAMロールまでterraformでリソース作成するのは結構骨が折れました、、

IAMロールだけコンソールで作成、
もしくは、お試しでBuildProjectをコンソールで作成してみて、
自動生成されたIAMロールのARNをコピーしてcodebuild.tfにハードコーディングでもいいんじゃないかな
と思いました

この記事が誰かほかのterraformerのお役に立てれば幸いです

次は codepipelineをterraformで作る に挑んでみたいと思います

0
1
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
0
1