# 概要
GitHub Enterprise Cloud上のリポジトリから社内ネットワークにつなぐことのできるCI環境が求められた、かつ、GitHub Enterprise Server上のリポジトリからGitHub Actionsを使いたいという要望が出たため、社内ネットワークに接続可能なオートスケールするGitHub Actions Self-hosted Runner環境を構築しました。
AWSサービスやTerraformといった直接的な技術はもちろん、開発や運用を楽にするための方法(IaCや監視など)といった生産性を上げるために大事なことや、サービスを開発する上で必要な要件定義やドキュメント作成などを経験することができました。
# 関わった部分
要件定義・設計、実装、テスト、ドキュメント作成、ルール策定、運用保守のフェーズに関わりました。5〜6人で構成されたチームでモブプログラミングを用いて開発を進めました。リリースまでに3ヶ月程度要しています。リリース後は他のタスクと並行して運用改善を進めております。
基本的にモブプログラミングで開発は行っておりましたが、チーム内で技術を共有するほどではない簡単な改善を自主的に行っています。また、気づいたことや改善点は積極的に素早く相談したりタスク化するなど、自らが当事者となって開発を行っておりました。
# 利用技術
- AWS
- サービス: IAM, SecretsManager, EC2(ASG, AMI, userdata), S3, VPC, Route53, API Gateway, Lambda, CloudWatch(Logs, Metric filter, Metric Alarm, SNS, Chatbot)
- 構築、運用自動化、監視のために利用
- Terraform
- AWSリソースの管理、デプロイのために利用。ほぼ全てのリソース(AMI, Lambda, Chatbot以外)を管理しています。
- Packer
- EC2のマシンイメージ(AMI)の管理、デプロイのために利用
- Serverless Framework
- Lambda関数の管理、デプロイのために利用
- TypeScript
- Lambda関数の実装に利用
- Datadog
- メトリクス収集、アラートのために利用
# 詳細
## リリース前
まず、社内での求められているSelf-hosted Runner環境がどのようなものかを考え、要件を洗い出しました。次に、構築を助けるいくつかのライブラリ(OSS)があることがわかったので、それらを試したのち、我々の要件に一番近い利用ができるライブラリA(AWS上での構築を目的としたTerraformモジュール)を利用することとしました。
そのTerraformモジュールを使うことでOrganizationごとにオートスケールするランナー環境を構築することができましたが、要件に合わない部分がいくつかあったため、下記のような工夫を行いました。(ちょっと細かく書きすぎたかもしれません)
- 社内ネットワークに繋げるためのVPN、サブネットの構築
- GitHub-hosted Runnerに近い構成のAMIを構築するためのPackerファイルを作成し、毎週作成&適用をするCI/CDワークフローを用意。
- ランナーを動かすEC2インスタンスのマシンイメージ(AMI)はGitHub-hosted Runnerと異なるため && 上記Terraformモジュールの仕様でAMIを更新するたびに`terraform apply`する必要があるため
- Production/Staging環境 * Cloud/Server環境 * Organizationを実現するためのTerraformモジュールの作成(ライブラリAをさらに丸め込んだモジュール)
- ライブラリAの更新やリソースの構成変更を手軽に検証できるようにするため
これらを行ったのち、ドキュメント作成やルール策定を行い、その後リリースしました。要件定義・設計を十分に行って開発したため、スムーズに社内利用が進み、手戻りの発生を抑えることができました。
## リリース後
リリース後は、運用保守をさらに楽にするために以下のような工夫を行いました。
- ランナー登録だけをするためのスクリプト作成とスケジュール実行の設定
- 常時1台ランナーがGitHubに登録されている必要があるため
- インスタンス起動時のエラーを発見するためのエージェント配置、メトリクス作成、アラート設定
- cloud-initのエラーは発生しても気付くのが難しいため
- ランナー数などの情報をDatadogへ定期的に記録するLambda関数の作成、アラート設定
- 何かしらが原因でインスタンスがずっと起動してしまっている、起動しているインスタンスが多すぎるなどの、意図せず大きな課金が発生してしまうことを防止するため
- インスタンス起動時にエラーが起きた場合に自動でTerminateするための設定
- その他諸々細かい変更
これらにより、我々の運用コストを減らしつつ、品質を向上させていっています。
今後はさらに以下などを行う予定です。
- 不必要なリソースの自動削除
- Renovateを自前で動かすことによるTerraformモジュールや利用ライブラリを自動更新
- 自動で`terraform apply`をする際にplan内容を自動テストするなどのTerraform運用改善