【クラウドネイティブ会議】「誰も触りたくないTerraform」を生まないために――利用者と管理者で変わるモジュール設計
クラウドネイティブ会議から、Terraformのモジュールが複雑化する原因と、それを防ぐための設計指針を解説したセッションを紹介する。
6:00
クラウドネイティブ会議のセッション「Terraformモジュールはなぜ『魔境』化するのか」では、株式会社スリーシェイクのSREである羽山公平氏が、モジュールが複雑化する原因と設計指針を解説した。重複を減らすために作ったモジュールも、要件に応じて変数や条件分岐を増やせば、内部を読まなければ何が作られるのかわからない状態に陥る。羽山氏はDRY原則の誤解と利用者を考えない設計を問題として挙げ、ホワイトボックスとブラックボックスを使い分ける方法を示した。
再利用しやすくするための善意が、モジュールを複雑化させる
「Terraformモジュールは、なぜ『魔境』化するのか」と題して登壇したのは、スリーシェイクのSRE、羽山公平氏である。羽山氏は冒頭、会場の聴衆にTerraformやTerraformモジュールを利用しているかを問いかけ、多くの参加者が手を挙げるようすを確認した。
本セッションで扱うのは、すでに複雑化したモジュールをきれいに修正する方法ではない。これからモジュールを作る人や、なぜモジュールが使いづらくなるのか疑問を持つ人に向けて、魔境化する原因と、その向き合い方を示すことが目的である。
では「魔境」とはどのような状態なのか。羽山氏は大量のvariableが定義され、countなどによってリソースが動的に生成される結果、モジュール内部の処理を読まなければ、何が作られるのかわからなくなった状態と説明した。
その出発点は、多くの場合、合理的に見える判断である。例えば、複数のS3バケットを作成する際、同じリソースを毎回記述するのは避けたい。そこで、ログ用やデータ用などに共通して使えるS3モジュールを作成する。
しかし利用が広がるにつれて、「ログを保存するならライフサイクルを設定したい」「コンテンツ配信に使うならバージョニングを有効にしたい」「暗号化やレプリケーションにも対応したい」といった要求が加わる。そのたびに変数やフラグが追加され、モジュールが管理するリソースも動的に増減するようになる。
作成者は、要件ごとに異なるリソースや依存関係を管理しなければならない。一方で利用者も変数を指定するだけでは最終的に何が作られるのかを判断できず、モジュール内部を確認する必要がある。
羽山氏は、コミュニティで広く利用されるVPCモジュールにも多数の変数があり、NAT Gatewayの設定だけでも複数のフラグが存在する例を示した。「柔軟に使えるように変数を追加していくと、作る側も利用する側も、モジュールの処理を見なければわからなくなります」と羽山氏。
魔境は最初から意図して作られるわけではない。重複を減らし、利用しやすくしようという善意が、結果として理解しづらい構造を生み出すのである。
DRY原則が避けるべきなのは、コードではなく知識の重複
なぜ、合理的に見えた共通化が失敗するのか。羽山氏が原因として挙げたのが、DRY原則(Don't Repeat Yourself)の誤解である。
DRYは「同じコードを繰り返し書いてはいけない」という意味で使われることが多い。しかしスライドでは、DRY原則について「コードを重複させるな」ではなく「知識を重複させるな」という原則であると整理された。
羽山氏は、アプリケーションコードとTerraformコードの違いにも触れた。アプリケーションコードは主に処理を記述する。共通する処理を関数として切り出せば、異なる場所からも再利用しやすくなる。
これに対してTerraformが記述するのはインフラの状態である。その状態は「誰が、何のために使うのか」というコンテキストに強く依存する。そのため、同じクラウドリソースを使っているという理由だけで、共通化すべき知識まで同じとは限らない。
例として示されたのが、ログ用S3バケットとデータ用S3バケットである。ログ用バケットの目的は監査やデバッグであり、一定期間を過ぎるとデータの価値は低下する。保存期間を定め、安価なストレージへ移行したり、期限後に削除したりする設計が考えられる。
それに対してデータ用バケットは、ビジネスの継続や収益に直結するデータを保存する。原則として永久保持、または長期保管が求められ、削除保護も必須となる。さらに個人情報や機密情報を扱う場合には、より細かなアクセス制御やログ取得も必要である。
同じS3であっても、目的、保存期間、削除方針、アクセス制御といった知識は異なる。両者を1つの汎用S3モジュールにまとめれば、一方の要求に対応するための変数が、もう一方にも持ち込まれる。その積み重ねがモジュールを複雑にする。「DRY原則とは、『コードを重複させるな』ではなく『知識を重複させるな』という原則です」と羽山氏。
したがって、ログ用とデータ用は用途ごとに異なるモジュールとして定義する方がよい。Terraform公式ドキュメントでも、優れたモジュールは、プロバイダーが提供するリソースを組み合わせ、アーキテクチャ上の新しい概念を定義するものとされている。
単なる「S3モジュール」ではなく「ログ用S3バケット」という概念を定義すれば、目的と責務が明確になる。何を含め、何を利用者に委ねるべきかを判断しやすくなり、共通化の範囲も絞り込めるのである。
利用者と管理者が同じなら、構成を隠さずシンプルに保つ
続いて羽山氏は、モジュールを設計する際には「誰のために定義するのか」を考える必要があると説明した。
重要なのは、職種名そのものではない。モジュールを利用する人が、その管理にも関わるのか、それとも提供された機能を利用するだけなのかという違いである。
利用者と管理者が同じ場合に適するのが「ホワイトボックス・テンプレート(共通化)」である。スライドでは、ターゲットを「SRE→SRE(管理も利用する)」と表現している。SREが自分たちのコードを整理し、リソースの配置や依存関係をきれいにまとめるための共通化である。
ホワイトボックスでは、クラウドリソースの構成を過度に隠さない。利用者自身が構成を理解し、複数の部品を組み合わせてシステムを作ることを前提とするためだ。
例えばAPIサービスを構築する場合、コンピュートリソース、IAM、ログなどを最小単位の標準部品として定義する。ECSやCloud Runなどの実行環境を部品化し、リソース構成や依存関係、そのドメインで常に必要となる設定をモジュール側に集約する。
一方CPUやメモリなどのスペック、コストに関わる設定、外部リソースへの接続先など、運用上の意思決定が必要な値は利用者に委ねる。どの部品を、どのように組み合わせるかも利用者が判断する。羽山氏は「SREが組み合わせて使うパーツだからこそ、魔境化させずシンプルに保ちます」と語った。
利用者と管理者が同じである以上、複雑性をモジュール内部に隠しても、将来それを理解し、保守するのは自分たちである。あらゆる用途に対応するために大量のフラグを用意するのではなく、構成を把握できる状態を維持することが、ホワイトボックスにおける基本方針となる。
専門チームが複雑性を引き受け、利用者には機能を届ける
利用者と管理者が異なる場合には、設計の考え方も変わる。羽山氏が示したもう1つの形が「ブラックボックス・カプセル化(隠蔽)」である。
スライド上のターゲットは「SRE→アプリ(利用だけする)」である。アプリケーション開発者はモジュールを利用するが、内部のインフラ構成までは管理しない。そこでSRE側が複雑性を引き受け、利用者には機能や価値を提供する。
ブラックボックスの目的は、構成の共通化ではなく、機能の抽象化である。「S3バケットを作る」「ロードバランサーを配置する」といった個別リソースを意識させるのではなく「セキュアなログ保存」「Webサイト公開」「APIサービス実行環境」といった機能そのものを提供する。
APIサービスの例では、コンピュートリソースだけでなく、ネットワークやセキュリティ設定まで含めて「APIサービス実行環境」という概念を定義する。利用者が入力するのは、具体的なリソース設定ではない。公開範囲や接続先、冗長構成の要否、データの機密度といった、目的やビジネス上の要求レベルである。
モジュール側は、その要求に応じて適切なリソース構成やセキュリティ設定を決定する。これにより利用者は専門外の知識による認知負荷を減らし、サービスを動かすことに集中できる。管理者側も、セキュリティや可用性に関する設計を標準化できる。
ただし、要求に応じて構成を変える以上、ブラックボックスの内部は複雑になりやすい。羽山氏は、この場合には魔境化を一律に避けるのではなく、利用者へ価値を届けるために受け入れる考え方を示した。「アプリ開発者に価値だけを届けるために、裏側の複雑性を引き受けます」と羽山氏。
ホワイトボックスの失敗は、知識の異なるものを無理に共通化する「間違ったDRY」によって生じる。一方、ブラックボックスは、利用者がインフラの詳細を意識しなくて済むように、高い抽象度を目指して複雑性を内部へカプセル化する。
利用者と管理者が同じホワイトボックスでは魔境化させず、シンプルさと透過性を重視する。それに対して利用者と管理者が異なるブラックボックスでは、専門チームが責任を持つことを前提に、利用者の体験を優先して魔境化を受け入れる。
重要なのは、複雑さそのものをなくすことではない。誰のためのモジュールなのか、誰がその複雑性を管理するのかを明確にすることである。この切り分けがTerraformモジュールを「誰も触りたくない魔境」にしないための設計判断となる。
- この記事のキーワード
この記事をシェアしてください
