terraform-aws-github-runnerを試してみた

こんにちは。KDDIの篠原です。
この記事はKDDI Engineer&Designer Advent Calendar 2021の5日目の記事です。
今回はSelf Hosted Runnerの管理をいい感じやってくれる[terraform-aws-github-runner](https://github.com/philips-labs/terraform-aws-github-runner)を使ってみたので使ってみた感触やハマりどころをご紹介します。

### terraform-aws-github-runnerについて
通常のGithubのGithub ActionsではActionsを実行するためのRunnerはあらかじめ用意されており、利用者はマシンのリソースを気にすることなく気軽にジョブを実行することができます。
しかしGithub Enterprise Serverの場合はGithub Actionsのジョブを実行するためのSelf Hosted Runnerを自分で用意する選択肢しかありません。
気軽に実行したい場合はEC2を立ち上げてSelf Hosted Runnerとすることができますが同時に実行するジョブが増えたときの負荷やジョブを実行していない時間帯はいい感じにインスタンスを落としておきたい場合はただ単にEC2のインスタンスを立ち上げておけば良いというものでもなくなってきます。
この課題を解決するためにSelf Hosted RunnerのAutoscalingをいい感じに行うためのオープンソースプロジェクトがGithubの公式ドキュメントでいくつか紹介されています。

紹介されている2つのリポジトリの比較表は以下です。

| 機能 |actions-runner-controller|terraform-aws-github-runner|
|-|-|-|
|ランタイム|Kubernetes|Linux and Windows VMs|
|どの単位でRunnerがスケールできるか|Enterprise, organization, and repository levels. By runner label and runner group.|Organization and repository levels. By runner label and runner group.|
|Pull-based autoscaling support|あり|なし|
引用元：https://docs.github.com/ja/actions/hosting-your-own-runners/autoscaling-with-self-hosted-runners

この記事では私が普段使い慣れているTerraformベースで作られているterraform-aws-github-runnerを試してみたのでご紹介します。

### 動作概要
![component-overview.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536302/83c0067a-ba06-8b56-c26d-0d6a2dd415fb.png)

コンポーネントの概要図です。terraform-aws-github-runnerのGithubリポジトリより引用。
AWSの各種コンポーネントを駆使してSelf Hosted Runnerの管理をするシステムがTerraformのモジュールとして提供されており、簡単な.tfファイルを書けば`terraform apply` 1発で立ち上がります。
Github Appの設定を行った後、git pushなどのworkflowをトリガーする操作を行うとGithub ActionsのWebhookをAPI Gatewayが受け取り、Self Hosted RunnerがSpot Instanceとして立ち上がります。
workflowの実行が完了すると自動でSpot Instanceは削除されます。
一通り触ってみた後の感触としては

- 面倒なホストの管理が要らない
- workflow1つに対してSpot Instanceが1つ立ち上がるので同時に複数のworkflowが動く場合にもスケールする。自動テストを多くのリポジトリで回している場合など、多くのworkflowが並行して動いている場合はありがたいですね。
- 待機状態のSelf Hosted Runnerを作っておくことが可能。日中の時間帯のみ立ち上げておいて素早くworkflowを動作させるみたいなこともできます。
- Spot Instanceを活用し、workflowの実行が終わるとすぐに落ちるのでEC2立ち上げっぱなしによる無駄な費用がかからず、節約になる。

単純にSelf Hosted Runnerを大きなインスタンス1台で運用する方式よりも多くのメリットがあると感じました。

### ハマりポイント

構築中にいくつかハマりポイントがありました。

#### インスタンスタイプには注意！

t3.nanoのインスタンスタイプでRunnerを立ち上げ、Terraformの実行を含むworkflowを実行したところ

```
Error: Unrecognized remote plugin message: 

This usually means that the plugin is either invalid or simply
needs to be recompiled to support the latest protocol.
```

のエラーが発生しました。どうやらインスタンスのメモリが不足していたようです。
Self Hosted RunnerでTerraformの実行を行うには最低でもt3.microは必要でした。

参考：https://dev.classmethod.jp/articles/terraform-error-unrecognized-remote-plugin-messag/

#### Self Hosted Runnerの登録が前もって必要

Github Actionsの仕様上1つもSelf Hosted Runnerが登録されていない状態でworkflowを実行すると必ず失敗してしまいます。

リポジトリの中ではSelf Hosted Runnerをdockerで立ち上げ、すぐに落とす方法が紹介されています。この辺りは少し面倒ですね。

```
docker run -it --name my-runner \
    -e RUNNER_LABELS=selfhosted,Linux,Ubuntu -e RUNNER_NAME=my-repo-docker-runner \
    -e GITHUB_ACCESS_TOKEN=$GH_PERSONAL_ACCESS_TOKEN \
    -e RUNNER_REPOSITORY_URL=https://github.com/my-org/my-repo \
    -v /var/run/docker.sock:/var/run/docker.sock \
    tcardonne/github-runner:ubuntu-20.04
```

### まとめ
Self Hosted Runnerの管理をいい感じやってくれるterraform-aws-github-runnerをご紹介しました。
Github Enterprise Serverを普段使っていてGithub Actionsの活用を考えているプロジェクトでAWSとTerraformを活用している場合はすぐに導入できるので試してみてはいかがでしょう？