AmebaPlatformにおけるTerraform実行時間の圧倒的改善
メディア統括本部 サービスリライアビリティグループ(SRG)の谷成です。
#SRG(Service Reliability Group)は、主に弊社メディアサービスのインフラ周りを横断的にサポートしており、既存サービスの改善や新規立ち上げ、OSS貢献などを行っているグループです。
本記事は、GitHubActions上で実行されているTerraformの実行時間を改善した活動について紹介する記事となっております。
最初に今回使用している技術(サービス)各環境のterraformのPlanの実行とApplyの実行のタイミング現状の把握原因考察と修正プランPlan/ApplyのGitHubActions上での実装health checkの実装改善結果終わりに
最初に
AmebaPlatformでは基本的に全てのインフラリソースをterrafromで管理しています。サービス提供開始時は利用プロダクトもそこまで多くなくリソース数もそこまで多くなかったのですが、時間が立つに連れリソース数や利用プロダクト数が増加し、リソースを追加を確認するための で時間を要し、更に で時間が要求されるようになっていきました。(もちろん失敗した時は修正してやり直しが必要なので、かなりの時間が要求されます)
セキュリティグループやALBのListernerRuleなどのリソースを変更したり、リソースのバージョンアップを行いたいなどの要件は数多くあり、利用ユーザ全員がこのような操作を行うのに多くの時間を要する状況が長く続いていました。
本記事では、この状況を改善するためにGitHub Actions上で実行されるterraformの改善を行った活動について紹介します。
今回使用している技術(サービス)
- terraform
- GitHub Actions
各環境のterraformのPlanの実行とApplyの実行のタイミング
基本的に特定の環境用のbranchに対してPull Request(PR) を出したタイミングでPlanが走って、他の人にレビューをしてもらい、マージするとApplyが走る仕組みとなっております。
例えばdevlop環境に対してPlanを行いたい時はdevelop branchに対してPRを出しPlanの内容を確認後、問題なければmergeしてApplyを実行する形になっています。
現状の把握
肌感としては、Plan/Applyに時間がかなりかかっていたが改善した後に実際どのくらい改善できたかを計測できるように現状どのくらい時間がかかっているかを計測しました。python scriptでGitHub APIを叩き一ヶ月分のPlanやApplyの時間を取得することから始めました。以下がscriptから得られた結果になります。
上記の結果より中央値を見てもPlan/Apply共に実行に5分以上時間がかかっている事がわかります。
原因考察と修正プラン
原因については心当たりがあり、当初プロダクト数が少なかったこともあったのでPlan/Apply共に全プロダクトに対して実行をしていました。もちろんプロダクト数が増えるごとにPlan/Applyの実行時間が増加していきました。更に自分の変更していない部分で差分がでてしまった場合は大変で、その変更について調査し解決する必要がありました。
そこで、修正プランを考え、Github上で変更のあったプロダクトだけをPlan/Applyを実行するように変更することにしました。
ただし、この方法では今までは全部Planを走らせていた事によって気がつけていた変更に気がつけなくなったり、更新がほとんど無いプロダクトに関してはPlanがずっと行われない状況が続き、いざ実行しようとすると動かなくなる事態が想定されます。
障害発生時にこのような状況に陥るのは避けたいので一日に一回全てのプロダクトに対してPlanを実行するワークフローを用意することとしました。
Plan/ApplyのGitHubActions上での実装
簡単にterraformは下記のディレクトリ構成となっております。
まず、Planを走らせる場合、どのサービスに変更があったのかを検知する必要があります。これはコマンドを用いて、変更のあったディレクトリのパスを取得します。(Scriptは例外の処理などが多数含まれているため割愛します)
ディレクトリのパスとPR番号などを入れたユニークなファイル名で作成してアップロードします。
アップロード場所は当初S3を想定していたのですが、GitHub Actionsにはartifactと呼ばれるファイルをアップロードできる場所が用意されている事を教えてもらったので、そちらを使うことにしました。サイズ制限、保持期間、ファイル数、ファイル名長などの制限がありますが、どれも問題なさそうと判断することができました。
Planの結果を確認して問題がなければApplyを走らせます。こちらは先程紹介した通りユーザがマージを行ったタイミングでApplyが走ります。ApplyのタイミングではPRの番号などを入れて作成したユニークなパスを利用して、アーティファクトからダウンロードしてきます。ダウンロードで取得したファイルを元にPlanで確認を完了したプロダクトに対してApplyを走らせます。
health checkの実装
ヘルスチェックに関してはGitHub Actionsのcronの機能を利用して平日の7時に全プロダクトに対してPlanを実行するように実装しています。更に手動で実行することもあるので GitHub Actionsの の機能を利用して手動実行が可能となっております。
更に今までPlan/Applyが失敗したときはemailでの通知しか行っていなかったのですが、失敗した場合はslackの特定のチャネルに通知して担当者や実行者が気が付きやすくなるように改善を行いました。これにより担当者や利用者が失敗した際にすぐに気がつけるようになりました。
改善結果
ここ一ヶ月の正直な値を掲載しております。
Maxの値が異常なものが出ており、数個異常な値を持っている物があったのでAverageの値は大きくなっていますが、中央値を見てみるとPlanの方が Applyの方が となっております。
Applyの方の時間がかかっているのは改善当時はEKSのセルフマネージドグループを使用していたので、terraform側でノードグループの更新などはなかったのですが、現在はkarpenterを導入しているので、マネージドノードグループの更新に結構な時間を要するためMaxとAverageの値が大きくなっている感じとなっております。
終わりに
本記事ではAmebaPlatformにおけるGitHubActionsを使用したterraformのPlan/Applyの改善を行った事例を紹介させていただきました。本活動により、今まで多くの時間がかかっていたPlan/Applyの実行時間を短縮し生産性を向上させることができました。
他にも生産性向上を見込める部分がありそうなので、改善を行いまたブログで紹介できればと思います。
SRG では一緒に働く仲間を募集しています。
ご興味ありましたらぜひこちらからご連絡ください。