Self-hosted GitHub Actions runners in AWS CodeBuild を試す
これ
AWS CodeBuild が GitHub Actions をサポート開始
Set up self-hosted GitHub Actions runners in AWS CodeBuild - AWS CodeBuild
- CodeBuild プロジェクトを使用して Webhook を設定し、GitHub ACtions ワークフローの yaml を更新して CodeBuild マシン上でホストされているセルフホストランナーを使用できる
- GitHub への認証は PAT か OAuth App を使う
まとめというかわかったこと
※間違ってることや、こうすればいいよなどがあったらコメントください。
良かった点
- セットアップは楽
- ephemeral である
- 起動時間は EC2、Lambda 共に 1 分程度だった
- 個人的には十分速い
- マネージドイメージに加えて Docker カスタムイメージを指定可能
-
jobs.<job_id>.runs-on
に-<image>-<image-version>-<instance-size>
を追記すると、設定不要で様々なアーキテクチャのイメージを使える -
jobs.<job_id>.container
は EC2、Lambda 共に動く
微妙な点
- 何ができて何ができないかの制約が不明
- ドキュメント充実させてくれ〜
- GitHub との接続は PAT か OAuth App のみ
- 個人に権限が紐づいてしまう
- GitHub Apps でやれないと業務利用は厳しい気がする
-
リポジトリとプロジェクトを 1:1 でしか紐づけられないOrg 全体で一個のプロジェクトとできないリポジトリごとに設定が必要個別に使う分にはいいが、横展開しようとすると無理ある- 2024/07/22追記: org、enterprise レベルの webhook に対応したらしい(未検証)
-
jobs.<job_id>.services
は Lambda で動かない- EC2 では動く
-
jobs.<job_id>.services.ports
へホストマシンからアクセスできない-
jobs.<job_id>.container
からのアクセスはできる - 何か設定が必要?
-
- プールできない
- やる方法ないよね多分?
所感
- 開発チーム内で使う分にはいいかも
- イネーブリングチーム的なチームが社内で横展開するにはむずいかなという感じ
- 「GitHub Apps 使えない」のと、「リポジトリとプロジェクトが1:1対応」の部分が致命的。それ以外はなんとかなりそう
- まだまだ登場したばっかで様子見感ある
- インターネット上の知見が少ない
- 実用始めると色々な問題でそう
- 今後に期待
続報
organization、enterprise レベルの webhook に対応したらしい(未検証)。
軽く調べた感じだと相変わらず OAuth App もしくは PAT しか対応はしてなさそう(そもそも enterprise レベルはその選択肢しかないのだが)。
AWS CodeBuild now supports organization and global GitHub webhooks - AWS
前提条件
- OAuth アプリか PAT を作成する
- OAuth アプリの場合は CodeBuild コンソール
- PAT の場合は CodeBuild コンソールか ImportSourceCredential API を使用する
- CodeBuild を GitHub アカウントに接続する
- CodeBuild コンソールでソースプロバイダとして GitHub を追加できる
GitHub OAuth アプリを作成する
コンソールを使用して OAuth アプリを使用してプロジェクトを GitHub に接続するには、 プロジェクトを作成するときに次のようにします。
プロジェクト作成時にソースプロバイダで GitHub を指定して、OAuth で接続をやるらしい。
プロジェクト作成
OAuth 確認画面
接続できた
GitHub リポジトリの指定が必要で、Owner 配下すべて、みたいなのができないかもしれない。
ステップ 1: Webhook を使用して CodeBuild プロジェクトを作成する
- ソースの選択
- 「GitHub OAuth アプリを作成する」でやった
- 「プライマリソースの Webhook イベント」のイベントの種類に
WORKFLOW_JOB_QUEUED
を選択- この設定をすると、ビルドが GitHub Actions ワークフロージョブイベントによってのみトリガーされるとか
- 「環境(Environment)」でサポートする環境イメージとコンピューティングを選択する
- Lambda 選んだらランタイム選ばされるんだけど、言語固有のものしかなくてどれ選ぶのが汎用的になるか謎
- buildspec は無視される(オーバーライドされる)とのこと
-
Buildspec will be ignored when you use CodeBuild to run GitHub Actions workflow jobs. Instead, CodeBuild will override it to use commands that will setup the self-hosted runner.
- ちゃんと注意書き出て選択できなくなってた
-
- デフォルト値を続行し、「create build project」を選択
-
1 validation error detected: Value 'codebuild-korosuke613_playground_github_actions_test-service-role' at 'roleName' failed to satisfy constraint: Member must have length less than or equal to 64
- エラー出た。デフォルトで出てきたロール名だと長すぎてダメってさ
-
codebuild-korosuke613_playground_github_actions_test
に修正した
-
webhook 管理画面に行くとちゃんと設定されてた。
一覧
詳細
ステップ 2: GitHub Actions ワークフローの YAML を更新する
-
jobs.<job_id>.runs-on
にcodebuild-<project-name>-${{ github.run_id }}-${{ github.run_attempt }}
を指定する-
codebuild-korosuke613_playground_github_actions_test-${{ github.run_id }}-${{ github.run_attempt }}
でいいかな
-
-
runs-on: codebuild-<project-name>-${{ github.run_id }}-${{ github.run_attempt }}-<image>-<image-version>-<instance-size>
で環境設定をオーバーライドできるらしい
動いた
Total duration が 1m4s なので、立ち上がりに 1m くらいかかってそう(Lambda)。
とはいえ十分速い。
cat /etc/image-id
image_name="al2023-container-minimal"
image_version="2023"
image_arch="x86_64"
image_file="al2023-container-minimal-2023.2.20231030.1-x86_64"
image_stamp="1b43-4b52"
image_date="20231101224236"
recipe_name="al2023 container-minimal"
recipe_id="220964eb-6acd-049e-d04f-a09b-7db8-0f27-0eb7c841"
image_name="al2023-container"
image_version="2023"
image_arch="aarch64"
image_file="al2023-container-2023.3.20240312.0-arm64"
image_stamp="b7f8-3251"
image_date="20240313015236"
recipe_name="al2023 container"
recipe_id="d3afd5de-b11c-9893-0ca3-693c-9b26-d044-fd09cc9b"
CodeBuild のプロジェクト画面
それぞれ期間が「47 秒間」、「1 分間 0 秒間」となっている。
CodeBuild上の実行時間はここ参照するのが良さそう。
ビルドログにはランナー立ち上げのログがある。
ephemeral runner であるため、ジョブ終了後にランナーは登録解除&破棄される。
ちなワークフロー
on:
pull_request:
jobs:
hello_world_default:
runs-on: codebuild-korosuke613_playground_github_actions_test-${{ github.run_id }}-${{ github.run_attempt }}
steps:
- run: echo "Hello World!"
- run: cat /etc/image-id
hello_world_arm:
runs-on: codebuild-korosuke613_playground_github_actions_test-${{ github.run_id }}-${{ github.run_attempt }}-arm-3.0-small
steps:
- run: echo "Hello World!"
- run: cat /etc/image-id
https://github.com/korosuke613/playground/pull/56/commits/afdbb53b8105bfd2dfdd0d6f6adcb216fe2c399a
複数リポジトリを同じビルドプロジェクトに紐づけられるか?
リポジトリ指定時に owner で止めてみる
- korosuke613/
- korosuke613
を指定したが、いづれも保存に失敗
リポジトリ指定時にワイルドカードを指定
- korosuke613/*
を指定し、保存したが、実行されず
ダメそうな雰囲気ある
Currently this feature update your Build Project using CodeBuild with multiple GitHub resources to automatically trigger CodeBuild isn't an available feature that CodeBuild provides. However Integrating your CodeBuild project into CodePipeline with fix this problem.
Use same CodeBuild project for multiple GitHub repositories
Docker の機能は使えるか on Lambda
services
と container
でやってみる。
❯ git --no-pager diff HEAD^
diff --git a/.github/workflows/codebuild-runner.yaml b/.github/workflows/codebuild-runner.yaml
index 347e9ab..1a85c44 100644
--- a/.github/workflows/codebuild-runner.yaml
+++ b/.github/workflows/codebuild-runner.yaml
@@ -4,11 +4,18 @@ on:
jobs:
hello_world_default:
runs-on: codebuild-korosuke613_playground_github_actions_test-${{ github.run_id }}-${{ github.run_attempt }}
+ services:
+ nginx:
+ image: nginx
+ ports:
+ - 8080:80
steps:
- run: echo "Hello World!"
- run: cat /etc/image-id
+ - run: curl http://localhost:8080
hello_world_arm:
runs-on: codebuild-korosuke613_playground_github_actions_test-${{ github.run_id }}-${{ github.run_attempt }}-arm-3.0-small
+ container: ubuntu
steps:
- run: echo "Hello World!"
- run: cat /etc/image-id
jobs.<job_id>.services
を指定
Set up job
時に Error: docker: command not found
エラーが出てしまった。
jobs.<job_id>.contaienr
を指定
なんとうまく ubuntu
イメージ上で動いた。
(その後のステップで失敗してるのは無視して良い)
jobs.<job_id>.services
と jobs.<job_id>.container
の両方を指定
もしやと思いやってみる。
❯ git --no-pager diff HEAD^
diff --git a/.github/workflows/codebuild-runner.yaml b/.github/workflows/codebuild-runner.yaml
index 1a85c44..96a3fec 100644
--- a/.github/workflows/codebuild-runner.yaml
+++ b/.github/workflows/codebuild-runner.yaml
@@ -9,13 +9,8 @@ jobs:
image: nginx
ports:
- 8080:80
- steps:
- - run: echo "Hello World!"
- - run: cat /etc/image-id
- - run: curl http://localhost:8080
- hello_world_arm:
- runs-on: codebuild-korosuke613_playground_github_actions_test-${{ github.run_id }}-${{ github.run_attempt }}-arm-3.0-small
container: ubuntu
steps:
- run: echo "Hello World!"
- - run: cat /etc/image-id
+ - run: cat /etc/os-release
+ - run: curl http://localhost:8080
Error: docker: command not found
ダメだった。
Docker の機能は使えるか on EC2
設定変更して EC2 を使うように変更
一応動作確認で https://zenn.dev/link/comments/07d0514de75ea6 を動かす。
ちゃんと動いた。
起動時間は Lambda とあまり変わらず
jobs.<job_id>.services
と jobs.<job_id>.container
の両方を指定
これと同じワークフロー動かす。 https://zenn.dev/link/comments/e5bf548a496853
動いた!が、ubuntu コンテナには curl 入っておらず
❯ git --no-pager diff HEAD^
diff --git a/.github/workflows/codebuild-runner.yaml b/.github/workflows/codebuild-runner.yaml
index 96a3fec..761d78d 100644
--- a/.github/workflows/codebuild-runner.yaml
+++ b/.github/workflows/codebuild-runner.yaml
@@ -13,4 +13,5 @@ jobs:
steps:
- run: echo "Hello World!"
- run: cat /etc/os-release
+ - run: apt-get update && apt-get install -y curl
- run: curl http://localhost:8080
まさかのサービスコンテナ起動時にレートリミット!めんどくさ!
Starting nginx service container
/usr/local/bin/docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit
Warning: Docker pull failed with exit code 1, back off 8.341 seconds before retry.
/usr/local/bin/docker pull nginx
Using default tag: latest
Error response from daemon: toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit
Warning: Docker pull failed with exit code 1, back off 9.637 seconds before retry.
/usr/local/bin/docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit
Error: Docker pull failed with exit code 1
しゃーないので ECR Public の nginx を指定する。
❯ git --no-pager diff HEAD^
diff --git a/.github/workflows/codebuild-runner.yaml b/.github/workflows/codebuild-runner.yaml
index 761d78d..334a658 100644
--- a/.github/workflows/codebuild-runner.yaml
+++ b/.github/workflows/codebuild-runner.yaml
@@ -6,7 +6,7 @@ jobs:
runs-on: codebuild-korosuke613_playground_github_actions_test-${{ github.run_id }}-${{ github.run_attempt }}
services:
nginx:
- image: nginx
+ image: public.ecr.aws/nginx/nginx:latest
ports:
- 8080:80
container: ubuntu
この場合 AWS 内のサービスからの pull になるが、自動でレートリミット無視されるのかはよくわかってない。
localhostでつながらんのだった
その後色々やった。
on:
pull_request:
jobs:
services-and-container:
runs-on: codebuild-korosuke613_playground_github_actions_test-${{ github.run_id }}-${{ github.run_attempt }}
services:
nginx:
image: public.ecr.aws/nginx/nginx:latest
container: public.ecr.aws/ubuntu/ubuntu:latest
steps:
- run: apt-get update && apt-get install -y curl
- run: curl --retry 5 --retry-delay 1 --retry-all-errors http://nginx
services:
runs-on: codebuild-korosuke613_playground_github_actions_test-${{ github.run_id }}-${{ github.run_attempt }}
services:
nginx:
image: public.ecr.aws/nginx/nginx:latest
ports:
- 8080:80
steps:
- run: curl --retry 5 --retry-delay 1 --retry-all-errors http://localhost:${{ job.services.nginx.ports[80] }}
normal:
runs-on: ubuntu-latest
services:
nginx:
image: public.ecr.aws/nginx/nginx:latest
ports:
- 8080:80
steps:
- run: curl --retry 5 --retry-delay 1 --retry-all-errors http://localhost:${{ job.services.nginx.ports[80] }}
- container と services の併用: 疎通可能✅
- services のみ: ホストから疎通できず❌
- 比較用に ubuntu-latest で同じことをやってそっちはうまく行った
- 何か特別な設定がいるのか??
services のみ
curl --retry 5 --retry-delay 1 --retry-all-errors http://localhost:8080
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (7) Failed to connect to localhost port 8080 after 0 ms: Couldn't connect to server
Warning: Problem (retrying all errors). Will retry in 1 seconds. 5 retries
Warning: left.
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (7) Failed to connect to localhost port 8080 after 0 ms: Couldn't connect to server
Warning: Problem (retrying all errors). Will retry in 1 seconds. 4 retries
Warning: left.
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (7) Failed to connect to localhost port 8080 after 0 ms: Couldn't connect to server
Warning: Problem (retrying all errors). Will retry in 1 seconds. 3 retries
Warning: left.
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (7) Failed to connect to localhost port 8080 after 0 ms: Couldn't connect to server
Warning: Problem (retrying all errors). Will retry in 1 seconds. 2 retries
Warning: left.
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (7) Failed to connect to localhost port 8080 after 0 ms: Couldn't connect to server
Warning: Problem (retrying all errors). Will retry in 1 seconds. 1 retries
Warning: left.
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (7) Failed to connect to localhost port 8080 after 0 ms: Couldn't connect to server
Error: Process completed with exit code 7.