はじめに
RevCommの宇佐美です。最近スタンディングデスクを買って、立ったり座ったりしながら仕事をしています。
RevCommでは、音声解析AI電話「MiiTel(ミーテル)」やAI搭載オンライン会議解析ツール「MiiTel Meetings」などを開発・提供しています。私は今年10月までMiiTelの認証基盤 (MiiTel Account) 開発プロジェクトで、Project Manager兼Sortware Engineerとして活動していました。
直近では希望によりプロジェクト異動をして、コールセンター機能とリアルタイム通信基盤を開発するチームに参加しています。今まで扱っていたものとは全く異なる技術を触っているので、日々わからないことだらけでエキサイティングです。
過去記事:
- MiiTel AccountのSLO: 測定と継続的な最適化の方法
- Cognito user pool で OpenID Connect を利用した外部 ID Provider によるサインインを実現する
今回はMiiTel Account在籍時にチームで行った、サービスの本番リリース(デプロイ)を週1回から日中随時に切り替えるという施策について紹介します。準備段階を含めて数ヶ月程度かかり、実際にリリースフローを切り替えたのは2023年9月半ばからでした。
すべてのサービス・チームでこういった施策を行うことができるかどうかは考慮が必要なところですが、この過程でリリースに関する体験や生産性が大きく向上したため、この機会に詳しく紹介したいと思います。
モチベーション
RevCommではMicroservices architectureを採用しており、リリースのタイミングは原則として各サービス・チームに委ねられています。とはいえ、多くのサービスでは週1回の決まったタイミングで、アクセスも比較的少ない夜間にリリース作業をしています。MiiTel Accountでも、元々は毎週水曜日の夜間9時ころにリリース作業を持ち回りで行っていました。
このやり方には、夜間なのでリリース後に障害が起きたときにユーザー影響を狭められる、開発者以外のステークホルダーからデリバリーのタイミングが予見・調整しやすいといったメリットがありました。
一方で、以下のようなデメリットも感じていました。
- 夜間作業が常態化する
- 週によってはリリースが大きくなりやすい(多くのPRが同時にリリースされる)
- 障害や想定外の挙動が発生したときの原因切り分けが難しくなる
こういったことを解決するため、日中かつ随時(オンデマンド)に、PR単位の本番リリースができないか模索し始めました。そのために行った施策については後述します。
あわせて狙った効果
日中リリースへの移行を考えたモチベーションとしては上記のとおりですが、この他にも副次的な効果として狙っていたのが開発生産性指標の向上です。
昨今、ソフトウェア開発の世界では開発生産性という言葉が脚光を浴びています。この開発生産性を計測する上で重要視されているのがFour keys metricsという指標です。
詳細は割愛しますが、チームの開発生産性を測る上で最も重要な4つの指標を定義したもので、一般的にはそれぞれ以下のように定義されます。今回の施策は、以下のデプロイの頻度向上を目的としたものということもできます。
- デプロイの頻度: 組織による正常な本番環境へのリリースの頻度
- 変更のリードタイム: commitから本番環境稼働までの所要時間
- 変更障害率: デプロイが原因で本番環境で障害が発生する割合 (%)
- サービス復元時間: 組織が本番環境での障害から回復するのにかかる時間
(エリート DevOps チームであることを Four Keys プロジェクトで確認する - Google Cloud)
これらの指標は密接に関連しているものとされます。一見すると直感に反するような気もしますが、デプロイ頻度が高いチームは変更障害率が低く、サービス復元時間も短いことが多いようです。
これは推測ですが、デプロイ(リリース)頻度を上げるためにはCI/CD環境などの運用自動化を推進したり、レビュー体制などを整える必要があることから、他の指標もこれらの施策の結果として向上する傾向がある、と理解しています。
復元時間に関しては、デプロイの粒度を細かくできることからビッグバンリリースを避けられ、障害発生時の原因特定が容易になる、という側面が影響していると考えられます。
また、これらの開発生産性指標が高いチームが多いと、そのサービスによる売上や収益といったビジネス上の価値にも直結するという指摘もあります。開発生産性が高いと、高速にフィードバックサイクルを回したり、市場の変化に柔軟に対応することが可能になるので、これは納得がいくものです。
このあたりの詳細はLeanとDevOpsの科学(原題: Accelerate)という書籍にまとまっていて、統計的手法によって検証されているため、開発生産性に関心がある方はぜひ手にとってみてください。
行った施策
ここからは、実際にリリースを週1回から日中随時に切り替えるために取った施策について紹介していきます。細かいものも入れるとたくさんありますが、大きいものとしては以下のようなことをしました。
E2Eテストの自動実行
MiiTel AccountではAPIの統合テストを用意していて、リリースの前後に本番環境やステージング環境などで実行していました。これによってリグレッションテストができ、デグレや予期しないバグなどを軽減することができていました。
ただ、テストの実行は手動でキックしていたのと、ローカルマシンからの実行だったため、環境差異によってテスト結果が一定にならないといった問題がありました。
リリースを随時に切り替えるための前提として、この統合テストをリリース時に自動で実行することに加えて、Autifyを使ってUIのE2Eテストも行うようにしました。この施策はMiiTel AccountチームのRaman Yachi (r-ym) が担当したもので、過去にブログ記事にまとめているので、興味がある方は一読いただければと思います。
MiiTel AccountチームのE2Eテスト自動化 - RevComm Tech Blog
これによって、リリース前後でサービスが正常に稼働していることを高い確度で手作業をほぼすることなく保証できるようになりました。
SLOによる性能担保
E2Eテストがあったとしても、リリース時点では検知できないようなレアケースや、負荷による性能劣化などはなかなか防ぎきれません。リリースを日中・随時で行うためにはサービスの安定稼働が大前提と考えていたので、SLO (Service Level Objective) が保てていることをまず確認した上で、もしリリース戦略の変更で数字が悪化することがあれば切り戻しも検討することを想定していました。
SLOに関する取り組みについては、前掲のブログ記事で詳説したのでこちらを参照ください。
MiiTel AccountのSLO: 測定と継続的な最適化の方法
幸いにして今のところ、リリース戦略の切り替え後もSLOのメトリクスが悪化していることはないようです。
リリースガイドラインの策定
日中随時にリリースするとはいっても、制限なくいつでもリリースOKとすることは考えていませんでした。休前日のリリースはトラブル時のサポート体制が整いづらかったり、PRによってはデータベースマイグレーションなど重要かつロールバック困難な変更を伴う場合もあるためです。
そこで、リリースの指針となるドキュメントを作成して、チームメンバーとも相談しながら最適なリリース戦略を策定しました。その中では主に以下のようなことを規定しています。
- 休前日のリリースを避ける
- 大規模障害発生日のリリースを避ける
- インフラやDBなどの変更は引き続き夜間に行う
- ユーザー影響が大きいリリースはQAを実施してからリリースする
今後も実際の運用を行っていく中で、よりよいリリースフローを模索しながらガイドラインも改善されていくものと思っています。
リリースノートの作成と投稿の自動化
RevCommでは、本番リリースを行ったあとにリリースノートをChange logとしてSlackチャンネルに投稿するという決まり事があります。これによって、他サービスの開発チームやサポート・プロダクトチーム、ビジネスサイドを含む関係者に変更内容を通知しています。
MiiTel Accountでは、リリースノートの作成自体はGitHubのRelease機能のおかげでほぼ自動でしたが、これをコピーしてSlackに投稿するという部分は手作業でした。
リリースが週1回であればそこまで手間になる作業ではありませんが、毎日のようにリリースがあると、これを手作業で全てやっていると明らかに非効率なうえ、うっかりリリースノートの投稿を忘れてしまう可能性もあります。
そこで、以下のようなフローで一連の処理を自動化しました。
- PRをmainからリリース用ブランチにマージ
- GitHub ActionsでRelease(リリースノート含む)を作成
- 同時にGitHub ActionsでCodeDeployをキックしてデプロイ開始
- デプロイ後、CodeBuildによるE2Eテストが成功したらLambdaをキック
- Lambdaが2.のReleaseを取得してリリースノートを作成し、Slackに投稿
Mermaidで図示するとこういう感じになります。
LambdaからGitHubのReleaseを取得するところでは、カスタムGitHub Actionsを使ってGitHub Apps tokenで認証しています。
このフローにより、こういった形でリリースノートがSlackに自動でポストされるようになりました。
細かい部分ではありますが、これも手作業を減らしてリリース作業を楽にすることに貢献した施策のひとつだと思っています。
(Slackアイコンはオンラインの商用フリー生成AIツールを使って作成しました🚀)
結果
これらのことを整備したあとに社内アナウンスをして、9月半ば頃から日中リリースへの切り替えを行いました。MiiTel AccountチームではLooker Studioを使ってFour keys metricsの集計を行っていますが、9−11月の合計リリース数が6–8月と比較して3倍ほどに増えました。
一方で、変更後もSLOを始めとしたサービスの性能面をキープできており、サービスの停止や遅延などのメジャーインシデントはゼロを保っています。
まとめ
実際にリリースを日中に変更してみて、やはり一番体感として大きいのは定常的な夜間作業がほぼなくなったことです。また、記載したような施策を行う過程でリリースに関するフローの大部分を省力化・自動化することができたため、リリース作業というもの自体がほぼなくなったような印象もあります。これはかなり体験としてよくて、ルーティン業務が大きく減って本来の開発に避ける時間が増えたのを感じます。
冒頭に記載したように、すべてのサービスで日中随時のリリースができるとは限りません。ただ、MiiTel AccountはMiiTel全体の認証を担っているミッションクリティカルなサービスで、わずかな間でも停止してしまうとMiiTel全体に影響を及ぼします。
それでも上記のような施策を一つずつ着実に実行していったことで、安定運営を保ったままリリース戦略を改善していくことができたと思っています。そして、こういった施策はリリース頻度だけではなくその他の開発生産性を改善したり、チームメンバーの健康や精神衛生、モチベーションも向上する可能性もあるので、検討する価値は大いにあるはずです。
RevCommでは機能開発はもちろん、運用改善や開発生産性向上などにも開発者が責任と裁量を持って取り組むことができます。興味がある方は、下記から採用情報をチェックしてみてください。
最後までお読みいただきありがとうございました。