AWS製ミニサービスによるトイル削減の取り組み事例の紹介と振り返り

Progateの小笠原です。本記事はadvent calendarの23日目の記事となります。

年末になって振り返りの時期となりました。粒度の大きな仕事はチーム/プロジェクトで振り返りを行うため、自分の中で整理が付けやすいのですが、粒度の小さなタスクに関しては振り返ることなく忘れられがちです。

今年はSREチームで非効率な業務や無駄なコミュニケーション(いわゆるトイル)を自動化や仕組み化で効率化/削減するというミッションをOKRの一つに置いていました。そこで行った2件の施策について導入経緯と効果を振り返りつつ紹介できたらと思います。

事例としてはありふれたもので新規性はありませんが、何かしら参考にしてもらうことがあれば嬉しいです。

施策1: 構成ドリフト検知サービスの導入

導入背景

弊社では2018年にterraformを導入して以降、新規で構築する基盤リソースは可能な限りすべてコード化して管理するようにしています。運用を続けているといろいろな課題が見えてきますが「構成ドリフト」の問題にもしばしば頭を悩まされてきました。

構成ドリフトとは、手動での変更など正規の手順以外で加わった変更によりterraformのコードと実際の基盤リソースの間で意図せぬ差分が生じることです。例えば緊急時のオペレーションや普段の業務の中でコードへの反映漏れがあると起こります。

構成ドリフトは早期に当事者が対応すれば問題にならないのですが、発生から時間が経つと差分の背景を掘り起こすのに手間がかかるようになります。また変更を加えた当事者すら背景を忘れていて、差分をどう直せばよいかを検討するのに必要以上に思い出しコストがかかるようになったりします。

正規の手順で変更を加えるタイミングでこの構成ドリフトが発覚すると、作業を中断せざるを得ず、基盤の設定変更のアジリティやタスクの作業効率、ついでに作業者の士気が大きく下がってしまいます。

f:id:shotaogasawara:20211222152219p:plain:w250:h250

それも半年に一回程度しか起こらないならともかく、これが週に何度か発生すると「コード化/IaCとはなんだったのか」という悲しみを感じるようになります。コードが最新の基盤の状態に一致してないとコード化の意味はないのです。

対策の検討

毎日terraformを定時に自動applyするという方法も対策の一つとして提案されたこともありますが、中身を確認せずにapplyすると思わぬ事故が起こる可能性がありリスキーです。

そこでもう少し安全なやり方として、毎日定時にplanコマンドを実行して差分が検出されたらslackに通知してコードの修正を促す仕組みを作ることにしました。

構成と通知サンプル

構成ドリフト検知サービスの構成
構成ドリフト検知サービスの構成

本サービスではCloudWatchのevent ruleを起点に、毎日朝7時にCodeBuildを起動します。CodeBuildの中では最新のterraformコードをpullして、stateごとにterraform planコマンドを実行して差分が検出されると以下のようにslackに通知を行って修正を促します。

ドリフト検知時の通知サンプル
ドリフト検知時の通知サンプル

このメッセージを見て、身に覚えがある人が以下のように自発的に対応するようにしています。

ドリフト対応例

導入と普及までの流れ

導入当初は溜まっていたドリフトが一斉に検知され頭を抱えました。とはいえ新しい仕組みは言い出しっぺが滑り出しまでは責任を持って実施しないと普及しないものなので、自分でまず一次調査を行い、関係してそうなオペレーションログから当事者を推測、呼び出してヒアリングする、というのを地道に行って解消していました。

そんなことをしばらく続けていると、だんだんチームメンバーもドリフト対応を自発的に行うようになってきました。良い感じです。

対応例

効果の振り返りと考察

仕組みを導入したら評価を行うのが世の常です。この仕組みがどのくらい使われたかを把握するべくslackの通知をもとに集計したところ、約1ヶ月の間に60件の構成ドリフトが検知されてました。

過去1ヶ月のドリフト検出件数
過去1ヶ月のドリフト検出件数

Progateではterraformのstateをサービス単位で分割しており粒度が細かいものがあることや、基盤の設定に手を加える時期は数が増えるということを考慮に入れても、数が多い印象です。毎日2個以上ドリフトが発生していた計算になりますが、これが検知されずに蓄積される可能性があったと考えると、、、早期検出できるようにして正解だったと思います。

なお、この仕組みの運用費は全構成要素を入れても月にたかだか数百円程度であり、費用対効果は良い印象です。サーバーレス構成様様です。

施策2: 本番環境向けバッチ実行サービスの導入

導入背景

ProgateのバックエンドではRailsを使っており、DBにパッチを当てる場合などにRails Runnerをよく利用しています。

ただ、Railsコマンドを叩くには本番環境のDBに接続可能なサーバにsshログインする必要がありました。一方で、該当サーバでは緊急時の対応を行う用途で様々なコマンドを実行できるため、セキュリティ上の制約からアクセス可能なメンバーが限られており誰もが手軽にアクセスしてコマンドを叩ける状態ではありませんでした。

そのためパッチを当てる際は権限を持ったメンバーに都度依頼してコマンドを実行してもらう、という運用となっていました。

f:id:shotaogasawara:20211223104019p:plain
パッチの実行依頼

(注)画像で出てくるambulanceという単語はバッチを実行するサーバの名称です。

f:id:shotaogasawara:20211223104048p:plain
パッチ実行時のやり取り

この運用にはコマンド作成者/実行者のそれぞれで以下のような辛さがつきまといます。

  1. コマンド作成者の辛さ
    • 実行担当者に事前に依頼と調整を行う必要が出る
    • 実行担当者の準備時間がリードタイムとなりタスクの進みが遅くなる
  2. コマンド実行者の辛さ
    • 依頼が割り込みで散発的に発生し、対応のために自身の作業を中断する必要が出る
    • 実行ログを実況するだけの退屈な仕事になることが多い

明らかに無駄が多く、両者にとってストレスフルで罪深い運用であることが理解できるかと思います。

対策の検討

問題の根本原因は本番環境のサーバへのアクセスが制限されていることです。

とはいえアクセス権限を開発者全員にばら撒くというのはセキュリティ上ありえないので、権限がなくても一部のコマンド(今回の場合はRails Runnerコマンド)だけは別の方法で実行可能にするのが良さそうです。そこで、本番環境のDBに接続してRails Runnerを起動できるバッチ実行用のミニサービスを別途用意し、slack経由で開発者であれば誰でも起動できるようにしました。

構成

ざっくりした構成は以下のとおりです。開発者が弊社のslack botサービス(通称8man)のI/Fで、実行したいコマンドに関するパラメータを渡すと、裏側でバッチ実行サービスを起動する仕掛けとなっています。

バッチ実行用サービスの構成
バッチ実行用サービスの構成

サービスの内側ではAWSのStepFunctionが起動し、通知とCodeBuildの実行を行います。このCodeBuildが本番環境にコンテナを立てて、渡されたパラメータに基づいてRails Runnerコマンドを実行してくれます。

ちなみにここでStepFunctionをCodeBuildにかぶせているのはバッチの通知結果を細かく調整したかったことと、構成図では省略していますが、いくつかLambdaの事前処理を噛ませたかったためです。要件によってはCodeBuildを直接呼び出すだけでも済むかも知れません。

コマンドを実行したい開発者はslack上で以下のようなI/Fで必要な入力パラメータをslack botに渡します。

  1. slack botの呼び出し
  2. パラメータ入力とsubmit

すると裏側でバッチ実行サービスが起動して以下のような通知を返してくれます

通知に含まれたリンクを辿るとCodeBuildの実行状況や実行ログ等を確認することができます。さらにバッチが完了するタイミングで以下の通知が来てバッチの成否が確認できます。

結果と考察

このバッチ実行用サービスは導入してから1ヶ月で開発者3人に計15回利用されました。一回あたりのコマンド作成者および実行者のコミュニケーションコストがそれぞれ15分とすると、ひと月あたり 7.5 時間の無駄が削減できたことになります。

バッチの実行要望自体それほど頻繁に発生するわけではないので、月によっては使用頻度が少ないこともあります。とはいえ、ひと月あたり1人日の稼働が浮くことがあると考えるとなかなか働きものの印象を受けます。運用費も施策1と同じく月額数百円で収まるためコスパは良いです。

何より、不要なコミュニケーションが減ることで開発者と運用担当者が互いに自身のタスクに集中できるようになったというのが重要です。こちらのサービスも引き続き活用する予定で、今後も無駄なコミュニケーションの削減に貢献してくれることを期待してます。

終わりに

Progateでのトイルの削減事例を2つ紹介しましたがいかがでしたでしょうか。どちらも似たような事例は多く、探せばオンライン上に実装例が転がっているのでもし似た課題があれば導入を検討しても良いかも知れません。

今回出てきたような非効率な運用作業はともすると当たり前のように日々の仕事に組み込まれていることがあります。しかし、確実にエンジニアの稼働を蝕み、普段の仕事の効率を落とす原因となっているので注意が必要です。

今後もトイルを見つけたら積極的に撲滅し、本質的な仕事に集中できる、楽しくてハッピーなエンジニアリングライフを来年も過ごせたらなと思います。最後まで読んでいただきありがとうございました。