CodeBuildがGitHub Actionsのself-hosted runnerをサポート

CodeBuildがGitHub Actionsのself-hosted runnerに対応した。

AWS CodeBuild now supports managed GitHub Action runners

本記事ではTerraformを使ってGitHub Actionsから起動される最小限のCodeBuildプロジェクトを作成する。

CodeBuildプロジェクトの作成(Terraform)

TerraformでCodeBuildプロジェクトを作成する。

CodeBuildプロジェクト

CodeBuildプロジェクトは以下のようになる。

variable "github_repository_url" {
  type = string
}

resource "aws_codebuild_project" "example_project" {
  name         = "example_project"
  service_role = aws_iam_role.example_codebuild.arn

  source {
    type     = "GITHUB"
    location = var.github_repository_url
  }

  artifacts {
    type = "NO_ARTIFACTS"
  }

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

service_roleに指定するロールは後述する。

sourceにはtypeGITHUBlocationにGitHubリポジトリのURLを指定する。
BuildSpecはself-hosted runnerでは無視されるので何も指定しない。

artifactsNO_ARTIFACTSを指定する。

environmentには利用したい実行環境を指定する。
» 利用できるイメージ

WebHookの設定

GitHub側に登録されるWebHookを定義する。

resource "aws_codebuild_webhook" "example_project_webhook" {
  project_name = aws_codebuild_project.example_project.name
  filter_group {
    filter {
      type    = "EVENT"
      pattern = "WORKFLOW_JOB_QUEUED"
    }
  }
}

project_nameには上記で作成されるCodeBuildプロジェクトの名前を指定する。

filter_groupにはpatternWORKFLOW_JOB_QUEUEDを指定する。

ロール

CodeBuildプロジェクトを実行するためのロールを作成する。

resource "aws_iam_role" "example_codebuild" {
  name = "example_codebuild"

  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect = "Allow",
        Principal = {
          Service = "codebuild.amazonaws.com"
        },
        Action = "sts:AssumeRole"
      }
    ]
  })

  inline_policy {
    name = "example_codebuild_policy"
    policy = jsonencode({
      Version = "2012-10-17",
      Statement = [
        {
          Effect = "Allow",
          Action = [
            "logs:CreateLogGroup",
            "logs:CreateLogStream",
            "logs:PutLogEvents"
          ],
          Resource = "*"
        }
      ]
    })
  }
}

inline_policyでポリシーを定義しているが、IAM Policyを別途作成してアタッチしてもよい。

Assume RoleにはPrincipalとしてcodebuild.amazonaws.comを指定する。

与える権限としてはCloudWatch Logsへの書き込み権限を与え、ログを出力できるようにしている。

Terraformのapply

上記で作成したTerraformをapplyする。
上記例ではgithub_repository_urlを変数としているので、何かしらの方法で外部から与える必要がある。
ここではterraform.tfvarsに変数の値を定義しているものとする。

github_repository_url = "https://github.com/yourname/yourrepo"

applyの実行配下のようになる。

$ terraform apply --var-file terraform.tfvars

すると以下のエラーが出る。

│ Error: creating CodeBuild Webhook: ResourceNotFoundException: Could not find access token for server type github
│   with aws_codebuild_webhook.example_project_webhook,
│   on codebuild.tf line 27, in resource "aws_codebuild_webhook" "example_project_webhook":
│   27: resource "aws_codebuild_webhook" "example_project_webhook" {

GitHubアカウントへの接続設定が別途必要となっている。

上記applyでCodeBuildプロジェクト自体は作成できているので、作成されたCodeBuildプロジェクトへAWSのコンソール(Web)からアクセスし、編集画面を開くと以下のような画面が表示される。

GitHubアカウントへの接続設定

「GitHubに接続」ボタンをクリックするとダイアログが表示されるので、GitHubアカウントとの接続設定を行う。

連携したら改めてterraform applyを実行する。

$ terraform apply --var-file terraform.tfvars

GitHubのプロジェクトの設定画面のWebHookメニューを確認するとCodeBuildプロジェクトのWebHookが登録されている。

GitHubのWebHook

このWebHookはTerraformでaws_codebuild_webhookリソースを削除すると自動で削除される。

GitHub Actionsの設定

GitHub Actionsのワークフローを設定する。

name: build
on:
  push:
jobs:
  build:
    runs-on: codebuild-example_project-${{ github.run_id }}-${{ github.run_attempt }}
    steps:
      - run: |
          aws sts get-caller-identity          

ポイントはruns-onに指定するランナー名をcodebuild-<CodeBuildのプロジェクト名>-${{ github.run_id }}-${{ github.run_attempt }}とする。

CodeBuildなので試しにaws cliを実行しaws sts get-caller-identityで実行ユーザを確認している。

動作確認

上記ワークフローを設定した状態でGitHubリポジトリにpushするとGitHub Actionsが実行され、CodeBuildプロジェクトが起動される。

GitHub Actionsの実行結果は以下のようになる。

GitHub Actionsの実行結果

実行に成功し、aws sts get-caller-identityコマンドも成功している。

AWSのコンソール(Web)から確認すると以下のようにCodeBuildプロジェクトも成功している。

CodeBuildの実行結果