ニフティ社内で使われているGitHub Enterpriseの管理者をしている石川です。
今年の4月にself-hosted runnerとしてCodeBuildを利用できるようになる嬉しいアップデートがありましたね。
CodeBuild-hosted GitHub Actions runnerは、4月時点ではリポジトリとCodeBuildプロジェクトが1対1で利用する方法しか取れませんでしたが、6月のアップデートでOrganizationやEnterpriseレベルでひとつのCodeBuildをRunnerとして指定することができるようになりました!
AWS CodeBuild now supports organization and global GitHub webhooks – AWS
ということで今回はOrganizationレベルでのRunner設定を試してみます。
CodeBuildの設定
Terraformだと以下のようなコードで設定できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
resource "aws_codebuild_project" "main" { ... source { type = "GITHUB" location = "CODEBUILD_DEFAULT_WEBHOOK_SOURCE_LOCATION" } environment { compute_type = "BUILD_LAMBDA_1GB" image = "aws/codebuild/amazonlinux-aarch64-lambda-standard:nodejs20" image_pull_credentials_type = "CODEBUILD" type = "ARM_LAMBDA_CONTAINER" } ... } resource "aws_codebuild_webhook" "main" { project_name = aws_codebuild_project.main.name build_type = "BUILD" filter_group { filter { pattern = "WORKFLOW_JOB_QUEUED" type = "EVENT" } } scope_configuration { name = "your-organization-name" scope = "GITHUB_ORGANIZATION" } } |
CFnでも作れるとよかったのですが、まだ対応していないようです。
Global webhooks and GitHub Enterprise webhooks are not supported by AWS CloudFormation.
Filter GitHub organization webhook events (AWS CloudFormation) – AWS CodeBuild
デプロイ前に注意が必要なのが、事前にGitHub認証情報をCodeBuildに手動で登録する必要があります。上記コードでは除いてしまってますが、PATやOAuthを使いSecret Managerに認証情報を格納した場合、CodeBuildのサービスロールにシークレットを取得する権限も必要となります。
参考:GitHub and GitHub Enterprise Server access in CodeBuild – AWS CodeBuild
CodeBuildのプロジェクトが作成されると同時にOrganizationにWebhookが登録されます。
管理者視点だとちょっと困ったことがあって、Webhooks一覧を見てもどのAWSアカウントのCodeBuildが呼ばれるのかここからだと識別できません。
GitHub認証情報管理の問題もありますし、Organization共通のRunnerは専用のAWSアカウントで管理した方がいいかもしれません。
Runnerの利用制限
Organization全体で使えるようなRunnerとして登録しつつも、利用方法に制限を加えたい場合があります。その場合はWebhookのFilterを使って制限を行います。
参考:aws_codebuild_webhook | Resources | hashicorp/aws | Terraform | Terraform Registry
1 2 3 4 5 6 7 8 9 10 |
filter_group { filter { pattern = "WORKFLOW_JOB_QUEUED" type = "EVENT" } filter { pattern = "your-workflow-name" type = "WORKFLOW_NAME" } } |
上記の例だと特定のワークフロー名で実行されたGitHub Actionのときのみ利用できるRunnerとなります。ほかにもいろいろな条件でFilterを作成することができます。
Terraformに限っては、まだ REPOSITORY_NAME
を使っての制限は作れないようなので、ここはアップデートを待ちましょう。
GitHub Actionsの設定
組織レベルでもリポジトリレベルでも変わりません。
WorkflowのYAMLに以下のフォーマットでRunnerを指定すれば動作します。
組織内のリポジトリであれば、これだけで利用できるはかなりお手軽ですね。
1 |
runs-on: codebuild-<project-name>-${{ github.run_id }}-${{ github.run_attempt }} |
参考:Tutorial: Configure a CodeBuild-hosted GitHub Actions runner – AWS CodeBuild
Jobを実行するまでのセットアップも課金対象
CodeBuildで実行する場合、毎回Runnerのセットアップと登録処理が行われます(buildspecの指定はできないため、どんなイメージを用意しても必ず実行される)。これが20〜30秒かかっていて、数秒で終わるJobだろうとこの時間が追加で実行時間として加算されます。
GitHub Actionsよりも格段に安いですが、Job実行時間以外も計算に入れておかないといけない点に注意が必要です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
[Container] 2024/08/21 02:13:32.738199 YAML location is /tmp/codebuild/readonly/buildspec.yml [Container] 2024/08/21 02:13:32.738443 Processing environment variables [Container] 2024/08/21 02:13:33.141679 Moving to directory /tmp/codebuild/output/src653/src/1c4cfb37_4d30_4c6c_bb71_0197866a72cd [Container] 2024/08/21 02:13:33.315509 Ignoring BUILD phase commands for self-hosted runner build. [Container] 2024/08/21 02:13:33.315542 Checking if docker is running. Running command: docker version [Container] 2024/08/21 02:13:33.317171 Warning: Docker not installed. GHA self-hosted runner build triggered by /actions/runs/10482304118/job/29033188127 Creating GHA self-hosted runner workspace folder: actions-runner Downloading GHA self-hosted runner binary % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 25 136M 25 35.1M 0 0 46.6M 0 0:00:02 --:--:-- 0:00:02 46.5M 65 136M 65 90.1M 0 0 51.1M 0 0:00:02 0:00:01 0:00:01 51.1M 100 136M 100 136M 0 0 51.9M 0 0:00:02 0:00:02 --:--:-- 51.9M Configuring GHA self-hosted runner -------------------------------------------------------------------------------- | ____ _ _ _ _ _ _ _ _ | | / ___(_) |_| | | |_ _| |__ / \ ___| |_(_) ___ _ __ ___ | | | | _| | __| |_| | | | | '_ \ / _ \ / __| __| |/ _ \| '_ \/ __| | | | |_| | | |_| _ | |_| | |_) | / ___ \ (__| |_| | (_) | | | \__ \ | | \____|_|\__|_| |_|\__,_|_.__/ /_/ \_\___|\__|_|\___/|_| |_|___/ | | | | Self-hosted runner registration | | | -------------------------------------------------------------------------------- # Authentication √ Connected to GitHub # Runner Registration √ Runner successfully added √ Runner connection is good # Runner settings √ Settings Saved. Running GHA self-hosted runner binary √ Connected to GitHub Current runner version: '2.319.1' 2024-08-21 02:14:00Z: Listening for Jobs 2024-08-21 02:14:04Z: Running job: schedule_task 2024-08-21 02:14:17Z: Job schedule_task completed with result: Succeeded √ Removed .credentials √ Removed .runner Runner listener exit with 0 return code, stop the service, no retry needed. Exiting runner... |
リポジトリごとにビルド費用を算出できるか
CUR/CUR2 で確認しましたが、CodeBuildのビルドステータスにあるイニシエータの情報はありませんでした。CloudWatch Logsに出力できるCodeBuildのログからもリポジトリの情報は標準では出力されておらず。残念ながらCURやCodeBuildのログから算出することはできませんでした。
なので、ちょっと手をかけて算出する必要があります。
- ざっくり分かればいい
- 該当のRunnerが使われているWorkflowを特定
- Actions Usage Metricsから実行時間を確認
- 参考:Viewing usage metrics for GitHub Actions – GitHub Enterprise Cloud Docs
- 詳細に算出したい
- EventBridgeには欲しい情報が揃っていたので、それをS3に保存してAthenaで集計
- EventBridge → Firehose or Lambda → S3 ← Athena
- 参考:Build notifications sample for CodeBuild – AWS CodeBuild
まとめ
- 組織レベルのRunnerを作るのは簡単
- GitHub Organization ownerの認証情報管理とRunnerの置き場はちゃんと考える必要がある
- リポジトリごとの利用量や費用算出は一手間かければできる
CI/CDを組織全体で共有管理している場合は、とても嬉しいアップデートですね。
一方各アカウントでCI/CDを管理している場合は、Organization owner権限が必要なポイントがあり、複数リポジトリで利用したいから使いたいという用途では少々使いにくい面もあります。
GitHub認証情報をどう管理していくかという問題とも紐づいているため、そこも考慮して利用を検討していくといいのではないかと思います。