こんにちは。データ・AI戦略部 SREチームの小野です。 2020年8月に中途で入社し、管理画面やAPIの開発、インフラ構築、サービス改善などに携わってきました。
SRE(Site Reliablity Engineering)チームでは、サービスやプロダクトの信頼性の向上を図るために、業務プロセスの改善に日々取り組んでいます。システム運用の自動化・効率化も職務の一つで、最近は特に「インフラ構築・運用の改善」に力を入れています。
弊社では、お客様の嗜好に合わせた「食」の情報を「ぐるなび」サイトなどのサービスからお届けしており、これらのサービスは、クラウドやオンプレといったインフラ環境で動いています。言い換えれば、「インフラ環境がなければ、サービスをお届けすることができない」ということになります。そのため、インフラ構築・運用の改善は、サービスの品質やお客様満足度を向上させるものであり、SREチームの務めだと感じています。
本記事では、TerraformとTerraform Cloud Business(以下、TFCB)を導入して、チーム内のインフラ構築・運用の課題を改善した話をお伝えしたいと思います。
目次
インフラ構築・運用における課題
2018年頃から弊社内ではAWSやGCPといったクラウドサービスの利用が増えています。 私の所属する部門でも新規で構築するサービスはクラウド上で構築することが前提となっていたり、オンプレからクラウドへ移行する動きが活発化してます。 私も最近、AWS上でインフラ環境を構築しました。
このインフラ環境はとあるAPIコンテナを稼働させるためのものでしたが、管理するAWSサービスが10個以上にもなりました。そして、インフラの構築・運用を検討する段階で下記のような課題が出てきました。
<構築課題>
- 検証・テスト・本番環境ごとにインフラ環境を構築するため、構築コストが高い
- 設定項目を全てドキュメント化し、常に最新の状態に保つことが困難
<運用課題>
- 構築担当者に設定変更やプロビジョニング作業が集中するなど属人化してしまう
- 案件ごとに異なる手段でインフラ環境を運用し、チームで管理する仕組みがない
恐らく、誰にでも一度は感じたことのある課題だと思います。
構築課題改善に向けてのアプローチ
構築課題は「手作業の割合が多い」ことに特に課題を感じました。AWSのコンソールからぽちぽちボタンを押してリソースを作成したり、設定パラメータを一つずつドキュメントにまとめていくのは誰の目から見ても大変だと思います。
そこで、インフラのコード化(Infrastructure as Code: 以下、IaC)に着目しました。 IaCとは、インフラの設定をプログラミングすることで、以下のようなメリットを得ることができます。
<メリット>
- コード化による設定項目の明文化、及び、流用における効率的な構築作業を実現する
- GitHubなどでバージョン管理することで、インフラの最新の状態を常に把握できる
つまり、インフラ環境をコード化し、流用することで手作業の割合を減らし、開発者の管理負担を軽減できる状態を作れると考えました。以下がその予想図です。
そして、実際にIaC化に取り組んだ結果、以下の成果をあげることができました。
<成果>
- 異なる環境でも瞬時に同じインフラ環境を構築できるようになった
- 「ソースコード == 最新の情報」となり、作成するドキュメント量が1/3以下になった
Terraformを採用
SREチームでは、HashiCorp社が開発したTerraformをIaCツールとして採用することにしました。
<採用理由>
- AWS、GCP、Azure、オンプレなど様々な環境下で利用可能
- 文法が簡単で、プログラミングチックに記述できる
- リソースをモジュール単位に分割でき、他案件で使いまわせる
resource "aws_instance" "default" { ami = "ami-*****************" instance_type = "t2.micro" tags = { Name = "TEST EC2 Instance" } }
※ AWS EC2のソースコード例
特にSREチームでは、AWS、GCP両方のクラウドを扱うため、マルチクラウド対応であることはとても魅力的でした。
運用課題解決に向けてのアプローチ
どちらかというと、構築課題よりは運用課題の方が解決すべき課題として重要でした。構築担当者が案件から抜けた場合、インフラ環境の維持が困難になるためです。これは、サービスの信頼性を担保するSREの観点から見てもあまりよろしくありません。 運用課題は「運用フローに多様性がある」ことに特に課題を感じました。構築担当者によって、プロビジョニングの作業手順やインフラ環境の管理方法などがバラバラに運用されているため、案件ごとにやり方を覚える必要があったためです。
そこで、「作業手順を標準化し、チーム内で統一する」、「インフラ環境をチームで管理できる仕組みを導入する」をスローガンに運用改善に乗り出しました。 作業手順の標準化は、CI/CDパイプラインを組むことですぐに解決することができました。 ※詳細は後述します
しかし、インフラ環境をチーム内で管理する仕組みについては想像以上に難しい課題でした。SREチームが管理するインフラ環境は、各案件・環境を全て合わせて「10環境以上」になります。また、管理する環境は今後も増加し、マルチクラウド化も進んでいくことを考えると「今、なんとかしなければいけない課題」だと再認識しました。 この問題を解決する手段として、プログラミングの知識が意外と役に立ちました。API開発に使ったGo言語では「インターフェース」という機能があり、プログラムの振る舞いを標準化することができます。
例えば、「開発環境ではRedisを使っていたけど、本番環境では急遽DynamoDBを使うことになった」などの経験はないでしょうか。DBの種類が変わってかなり焦ると思いますが、主なDB操作としては以下の通りです。
<主なDB操作>
- データを格納する
- データを参照する
- データを削除する
これらの振る舞いをインターフェースに定義しておけば、DBの切り替え時に大きな修正を必要としないプログラムを書くことができます。下記図の例では、操作したいDBのインスタンスを渡すことでDB切り替えを実現しています。
これと同じように開発者とインフラ環境の間に「構築・管理するためのインターフェース」を挟むことができれば、問題を解決することができるのではないかと考えました。イメージとしては、下記図のような感じです。
Terraform Cloud Businessを採用
Terraformを使ったインフラ管理を調査する過程で、TFCBを知りました。
TFCBもHashiCorp社のサービスで、Terraformで構築したリソースをクラウド上で一元管理することができます。また、簡単に「CI/CDパイプライン」を構築できる機能を搭載しているようなので、HashiCorp Japan社と協力してSREチームで2ヶ月ほどPoC検証を進め、システム導入が実現しました。 業務改善のためならば、新しい技術も積極的に採用するスタンスです。
元々、CI/CDパイプラインは、新しいバージョンのアプリケーションを提供するために実行する必要のある一連のステップをワークフロー化したものです。Terraformでインフラをコード化することで、GitHubでバージョン管理できるようになり、CI/CDパイプラインを組むことができるようになりました。
CI/CDパイプラインのステップは、とてもシンプルです。
<ステップ>
- Terraformで書いたソースコードをGitHubへPush
- PushをトリガーにTFCB上でジョブを実行
- リソースのレビュー
- リソースのプロビジョニング
- 実行結果をGmailやSlackで通知
CI/CDパイプラインを組むことで、属人化になりがちな作業が自動化され、かつ、標準化されました。 さらに、下記のTFCBの機能を活用することで、作業工数を削減することにもつながったのでいくつか紹介したいと思います。
活用することで作業工数が削減できたTFCBの機能
<TFCBの機能>
- リソースの一元管理
- GitHub連携
- レビュー機能
- ポリシーチェック
- サービス連携
1.リソースの一元管理
TFCBでは、Workspace単位でインフラ環境を管理します。
この方法であれば、クラウドの種類に関係なく同じ方法で管理できますし、状況に応じてワークスペースからインフラ環境の作成・削除も可能です。
<改善できたこと>
- マルチクラウドに跨って、インフラ環境の一元管理が可能になった
- チームでインフラ環境の管理がしやすくなった
- 管理外のリソースがなくなり、不必要なコストが発生しなくなった
2.GitHub連携
TFCBには、GitHubなどのバージョン管理システムと連携できる機能があるため、CI/CDパイプラインへの組み込みがとても簡単になりました。 今回の例で言うと、GitHubの特定のブランチにソースコードがPushされた時、TFCB上でジョブが実行されるようにしています。
<改善できたこと>
- 一連のステップを自動化し、作業工数を削減した
- プロビジョニング手順が標準化された
- 引き継ぎがとても簡単になった
3.レビュー機能
TFCBのWorkspaceでは、ジョブの実行をレビューできます。
上記の図では、「Plan finished」、「Cost estimation finished」、「Policy check passed」の3つのジョブが実行されたことを示しています。 「Apply pending」はリソースのプロビジョニングをするジョブなので手動実行する設定にしてますが、それ以外のジョブは、自動で実行されます。
Plan finishedでは、Terraformのリソースの作成、更新、削除情報を確認できるようになっています。
この機能のおかげで、予期しないリソースの更新・削除などに第三者が気付けるようになるため、インフラ環境の更新に安心感を持てるようになりました。
Cost estimation finishedは、インフラの運用コストを事前算出する機能です。運用状況次第でコストは変わっていくものなので参考程度に留めていますが、不必要なリソースがデプロイされていないか事前にチェックできて便利です。
※ 1時間: $0.013 1ヶ月: $9.63 の見積もり
<改善できたこと>
- インフラ環境の更新をレビューし、問題があればアラートを上がられる仕組みを構築した
- コスト見積もり機能で、不必要なリソースのデプロイを防げるようになった
4.ポリシーチェック
Policy check passedは、ポリシーに違反をしていないかチェックする機能です。
<ポリシー例>
- 命名規則通りのリソースが作られているか
- 不必要なPortを許可していないか
- リソースタイプは適切か
HashiCorp社が開発したSentinelという言語でポリシーをコード化(Policy As Code)することができます。これは、Terraform同様にポリシーの標準化やバージョン管理の恩恵を受けられるため、大変おすすめです。
Sentinelは簡単な文法で書ける言語なので、習得にはあまり時間がかからないと思います。
import "tfplan/v2" as tfplan // aws_instanceリソースを取得 ec2_instances = filter tfplan.planned_values.resources as _, rc { rc.type is "aws_instance" } # 許可するインスタンスタイプ allowed_types = [ "t2.micro", "t2.small", "t2.medium", ] // ポリシー: 許可されたリソースタイプを使っているか instance_type_allowed = rule { all ec2_instances as _, instance { instance.values.instance_type in allowed_types } } // mainからPolicyをチェックする main = rule { instance_type_allowed }
※ Sentinelで書いたポリシーコード
以下は、EC2の構築時に許可されたインスタンスタイプが使用されているかチェックした時の例です。
ポリシーに違反するとエラーになります。
<改善できたこと>
- ポリシーのコード化、標準化、チェックの自動化の仕組みを構築できた
- ポリシーをバージョン管理できるようになった
5.サービス連携
TFCBでは、SlackやGmailなどのサービスと連携させることが可能です。
この機能を使えば、CI/CDパイプラインが実行されたことを関係者に周知できるので、情報共有が楽になりました。
<改善できたこと>
- インフラ環境の更新を関係者に周知できる仕組みを構築できた
- レビュアーに通知することで、レビュー依頼を自動化できるようになった
今後のビジョン
「便利そうな機能だけど、GitHub ActionsでもCI/CDパイプラインを構築できるんじゃないの?」という声が聞こえてきそうです。 実際、GitHub Actionsを使えば、CI/CDパイプラインを組むことは可能です。
機能 | TFCB | GitHub Actions |
リソース一括管理 | O | X |
レビュー | O | O |
コスト見積もり | O | X |
ポリシーチェック | O | X |
実行結果通知 | O | O |
プロビジョニング | O | O |
しかし、それでもTFCBを導入したい理由が2点あります。
1点目は、「プロビジョニングツールをTerraformで統一できる」ことです。インフラの構築・運用において、各チーム、各部門ごとにプロビジョニングのやり方が違うのは非効率であると考えています。 TFCBを導入することで、プロビジョニングを標準化することができるのではないかと期待していますし、「同じツール・同じ手法を使うことで組織間の壁を減らす」こともSREの使命だと思います。
2点目は、TFCBには、「Terraformで開発したモジュールを登録できるRegistryという機能がある」ことです。 下記の図は、AWSのEC2やS3のリソースをモジュール化し、TFCBに登録した画像です。
モジュールを登録すると下記のようなコードが生成されます。
module "ec2-webapp" { source = "app.terraform.io/XXXX/ec2-webapp/aws" version = "1.0.1" # insert required variables here }
この機能により、稼働実績のあるモジュールを他案件で流用可能になり、構築効率を上げることができます。 この2点を踏まえ、今後のビジョンとなりますが、ぐるなび全体に提供できるプロビジョニングの仕組みを構築したいと考えています。
この方法は個人の創意工夫を妨げてしまうという見方もできますが、インフラ環境は、安定して稼働させることが何よりも大切だと思っています。そのためには、構築・運用方法を標準化し、属人化の防止・トラブルシュートの簡易化、ナレッジの蓄積などができる体制作りが必要だと考えます。 もちろん、より良いやり方や工夫があれば、積極的に取り入れていきたいです。
おわりに
構築課題はTerraformによるIaC化で、運用課題はTFCBを組み込んだCI/CDパイプラインを構築することで改善することができました。 SREチームのインフラ構築・運用において、よりシステマチックになったと自負しています。
今後もSREチームでは、既存のやり方を見直し、時には新しい技術を提案して、より効率的かつ効果的な仕事の仕方を模索していきたいと考えています。
ここまでお読みいただき、ありがとうございました。