こんにちは。@junk0612 です。
私が関わっているプロジェクトでは、現在プロジェクトのリリースの仕組みをチームメンバーに合わせて更新する作業が進んでいます。今回はそれについてお話しします。
プロジェクトのインフラ概要とリリース手順
まずはプロジェクトのインフラについて軽く説明します。
このプロジェクトでは、AWS EC2 上で Rails アプリケーションが動いています。EC2 インスタンスは Auto Scaling グループで管理されていて、基本的に2つ起動しています。また、アプリケーションとは別の EC2 インスタンスで Jenkins が動いていて、Terraform を利用する形で CI/CD を担当しています。
アプリケーションの新しい機能をリリースする場合、大まかに以下の流れで作業します。
- アプリケーションが依存するライブラリやツールをインストールしたベースとなる AMI を作成する1
- ベースとなるイメージ上にソースコードを配置し、
bundle install
やnpm install
などを実行したリリース用 AMI を作成する - リリース用 AMI を利用する起動設定を作成し、Auto Scaling グループに紐付ける
- Auto Scaling グループのインスタンスリフレッシュを利用して新しいイメージのインスタンスを立ち上げる
ですが、そこそこ歴史を重ねてきたプロジェクト2のため、いくつか問題点が出てきていました。
リリースの問題点
起動設定は利用しないことが推奨されている
起動設定のユーザーガイドに詳しく書かれていますが、起動設定は利用しないことが推奨されており、2022年12月31日以降は、EC2 の新しいインスタンスタイプが追加されても起動設定からは利用できないようになっています。
後継として起動テンプレートがリリースされていて、起動設定の設定をコピーして移行する機能も提供されているので、手動での移行自体は簡単にできますが、自動化の仕組みも修正する必要がありました。
Terraform に詳しいチームメンバーがいなくなった
Terraform は以前3のチームメンバーが採用したもので、時代を経るにつれ入れ替わりが起きて詳しいメンバーがいなくなっており、現在のチームではドキュメントを調べながら少しずつ修正することしかできなくなっていました。インフラ周りなので頻繁に修正することはありませんが、上記の起動設定の問題などと絡んで潜在的なリスクになっていました。
Jenkins のイメージがビルドできなくなっている
これが移行の最も大きな理由なのですが、Jenkins のインスタンス用 AMI をビルドするためのスクリプトに長いあいだ手が入っておらず、ビルドが通らなくなっていました。すでに Jenkins のバージョンも古くなっていましたが更新することもできませんし、下手をすると今動いているインスタンスが落ちても新しくインスタンスを立ち上げることができずに CI/CD ができなくなってしまう恐れもありました。
移行の話し合い
上記のような理由があったため、PO/PM やお客様側のインフラを事業横断して見ているエンジニアの方とも相談し「Jenkins と Terraform をやめて、新しいリリースの仕組みを作ろう」ということになりました。 Jenkins を修正する方針も議論にはなったのですが、次のような理由で移行に舵を切っています。
CI での移行実績がある
プロジェクトでは、RSpec を使ったユニットテストと、RSpec / Selenium / chromedriver を使った受け入れテストを書いており、Jenkins で CI として実行していました。 この中で、ユニットテストは以前 Jenkins から CodeBuild に移行した実績があるため、同様に受け入れテストも移行できそうでした。
Terraform のバージョンが古くなっている
Terraform のバージョンがかなり古くなっていて、間に破壊的な変更が伴うバージョンアップも含まれていました。これをバージョンアップするよりも、別の方法で置き換えたほうが今後の保守も行いやすいのではないかと話しました。
新しいリリース手順
相談と調査の結果、基本的に AWS で提供されている機能を利用する形に移行できそうだったので、次のような方針にしました。
- AMI の作成: Jenkins → EC2 Image Builder
- 起動テンプレートの作成・インスタンスリフレッシュによるリリース: Jenkins → CodeBuild
- 受け入れテスト: Jenkins → CodeBuild
ただ、最終形を一息に目指すとかなり時間がかかりそうだったので、まずは Terraform で行っていることを分解して、ブラウザから AWS マネジメントコンソールを操作するなどで代用可能な部分については操作手順を作って実行できるようにし、その後に自動化を進めていこうとしています。
ちなみに現在のステータスはこうなっています。
- AMI の作成: 移行中
- リリース: 手動でできるようになったので自動化中
- 受け入れテスト: 移行中だが完了の目処がたった
最後に
ということで「以前作られた仕組みが時間とともに負債化していたので、今のチームメンバーに合った仕組みに更新している」という話でした。いかがでしたか? 「継続的にメンテナンスしていれば起こらなかった問題では?」という声が聞こえてきそうな気がしてやや恥ずかしさもあるのですが、プロダクトがビジネス的に成長していく中にあってなかなかインフラ部分までは手が回っていませんでした。 今回の改善も機能改善が落ち着いてきたため提案して着手できた、という背景があります。
この記事が、誰かの一助になれば幸いです。