Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Terraformモジュールは、なぜ「魔境」化するのか

 Terraformモジュールは、なぜ「魔境」化するのか

Avatar for hayama

hayama

June 03, 2026

More Decks by hayama

Other Decks in Technology

Transcript

  1. Copyright © 3-shake, Inc. All Rights Reserved. 今回の登壇で話すこと、話さないこと 3 •

    なぜ魔境化するのか • 魔境化との向き合い方 話さないこと • 既にある魔境の綺麗にする方法 話すこと これから綺麗に作るぞ!という方、なんで使いづらくなるんだろ?と疑問を持っている方むけ
  2. Copyright © 3-shake, Inc. All Rights Reserved. 自己紹介 4 羽山

    公平 Sreak事業部で、主にAWSやGCP等のクラウド環 境でのSREをしております。 最近では、AIREといったAI+SREといった領域を 調べています!! @hymaaa_k
  3. 会社紹介 5 会社名 株式会社スリーシェイク 設立日 2015/1/15 Mission: インフラをシンプルにして イノベーションが起こりやすい世界を作る Vision:

    労苦〈Toil〉を無くすサービスを適正な価格で提供し続ける 2015 2016 2017 2018 2019 2020 2021 2022 0 50 100 従業員: 200名over Engineer 60% 所在地 東京都中央区銀座8丁目21番1号 住友不動産汐留浜離宮ビル7F  代表者 代表取締役社長 吉田 拓真 Googleクラウド・AWSの両方のエンジニアリングに強みを持つ 日本のSREをリードする インフラ・アプリ・データ・セキュリティ・AI 全方位で顧客の内製化を推進する伴走支援 あらゆるサービスを 連携するハブになる 「いいエンジニア」を あなたのチームに 事業者が抱える セキュリティリスクをゼロに あらゆるSaaSをノーコードで連携する クラウド型ETL/データパイプラインSaaS セキュリティ対策をワンストップで 実現する脆弱性診断SaaS ハイスキル人材の紹介とHR戦略支援の両輪で エンジニア組織の課題に併走 会社・事業部説明資料(SpeakerDeck)
  4. Copyright © 3-shake, Inc. All Rights Reserved. 魔境って何? 7 #

    variable.tf variable "complex_map" {} variable "enable_versioning" {} variable "enable_logging" {} variable "enable_replication" {} variable "enable_lifecycle" {} variable "enable_notification" {} # ... 大量に続く リソースが動的 variable の爆増 resource "xxxxxx" "xxxxx" { count = var.enable_nat ? 1 : 0 } moduleの処理を読まないと何が作られるのか分からない状態のこと
  5. Copyright © 3-shake, Inc. All Rights Reserved. なぜ生まれるの? 8 S3リソース作るぞ〜

    # env/dev/main.tf resource "aws_s3_bucket" "log" { bucket = "log-bucket" } resource "aws_s3_bucket_policy" "log" { ... } …
  6. Copyright © 3-shake, Inc. All Rights Reserved. なぜ生まれるの? 9 S3いっぱい使うから毎回書くの良くないな…

    よし!module作るぞ! # env/dev/main.tf module "log_bucket" { source = "./modules/s3" bucket_name = "my-log-bucket" } module "data_bucket" { source = "./modules/s3" bucket_name = "my-data-bucket" }
  7. Copyright © 3-shake, Inc. All Rights Reserved. なぜ生まれるの? 10 S3でlog貯めるなら、

    ライフサイクルは設定し てください S3でコンテンツ配信し たいから、 バージョニングしたい
  8. Copyright © 3-shake, Inc. All Rights Reserved. なぜ生まれるの? 11 柔軟にmodule使えるように変数追加しよう!

    # variable.tf variable "enable_versioning" { default = false } variable "enable_kms" { default = false } variable "enable_logging" { default = false } variable "enable_replication" { default = false } variable "enable_lifecycle" { default = false } # ... 要件に合わせて変数が増える
  9. Copyright © 3-shake, Inc. All Rights Reserved. モジュールを作る人も辛い 12 要件によって必要なリソースが違う!!

    それぞれ管理しないと # modules/s3 resource "aws_s3_bucket_lifecycle_configuration" "xxx" { count = var.enable_lifecycle ? 1 : 0 ... } resource "aws_s3_bucket_versioning" "xxx" { count = var.enable_versioning ? 1 : 0 ... }
  10. Copyright © 3-shake, Inc. All Rights Reserved. モジュールを利用する人も辛い 13 modules/s3はどのリソース管理しているのか

    処理を見ないと分からない!!! # env/dev/main.tf module "log_bucket" { source = "./modules/s3" enable_versioning = false enable_kms = true enable_logging = true enable_replication = false }
  11. AWSコミュニティが管理する汎用モジュール Copyright © 3-shake, Inc. All Rights Reserved. 身近にある魔境 14

    module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "5.0.0" enable_nat_gateway = true single_nat_gateway = false # ← この2つの組み合わせで挙動が変わる one_nat_gateway_per_az = true # ← enable_flow_log = true create_flow_log_cloudwatch_iam_role = true #iam_roleが作られる # ... 変数は v5.0.0 で 300 個近くある }
  12. Copyright © 3-shake, Inc. All Rights Reserved. この発想が良くない 16 S3いっぱい使うから毎回書くの良くないな…

    よし!module作るぞ! # env/dev/main.tf module "log_bucket" { source = "./modules/s3" bucket_name = "my-log-bucket" } module "data_bucket" { source = "./modules/s3" bucket_name = "my-data-bucket" }
  13. Copyright © 3-shake, Inc. All Rights Reserved. DRY原則 18 DRY原則とは「コードを重複させるな」ではなく「知識を重複させるな」という原則

    すべての知識はシステム内において、単一、かつ明確な、 そして信頼できる表現になっていなければならない。 — Hunt & Thomas『達人プログラマー』DRY原則 [1]
  14. Copyright © 3-shake, Inc. All Rights Reserved. アプリのコードとTerraformのコードの違い 19 •

    処理を記述 • 「誰が・何のために使うか(文脈)」に依存❌ ◦ ex)ソートの処理はどこでも同じ ▪ Logの検索 ▪ フロントエンドの描写 Terraformのコード • 状態を記述 • 「誰が・何のために使うか(文脈)」に依存 ◦ ex) s3は用途によって違う ▪ Log用のs3 ▪ コンテンツのs3 アプリのコード アプリケーションコードは「処理」を記述する。 Terraformコードは「状態」を記述する。 — Gosuke Miyashita「なぜインフラコードのモジュール化は難しいのか」 YAPC::Fukuoka 2025 [2]
  15. Copyright © 3-shake, Inc. All Rights Reserved. アプリコードにおけるDRY 20 item_sort

    user_sort log_sort 共通するsortする処理 コード 切り抜いて DRY達成 処理を記述 def sort(list, key) 知識の単一化=DRY達成 切り抜いたある処理は 処理だけを使いまわせる
  16. Copyright © 3-shake, Inc. All Rights Reserved. インフラコードにおけるDRY 21 aws_s3_bucket

    lifecycle versioning log用のs3 コード まとめて DRY達成 状態を記述 module log_bucket 知識の単一化=DRY達成 data用のs3 aws_s3_bucket lifecycle versioning aws_s3_bucket module data_bucket インフラリソースには文脈があ るので文脈ごとにグループ化
  17. Copyright © 3-shake, Inc. All Rights Reserved. 同じ S3 だけど、「知識」は違う

    22 目的     :監査・デバッグ データの性質 :一定期間で価値が低下 削除保護   :不要(コスト優先で消す) アクセス制限 :管理者のみ ライフサイクル : x日で削除・安価なストレージへ ログ用のS3 目的     :ビジネス継続・収益 データの性質 :長期間に渡り高い価値を持つ 削除保護   :必須(事故=事業停止) アクセス制限 :細かい(個人情報・機密情報) ライフサイクル : 原則永久保持 or 長期保管 データ用のS3 「同じリソース」や「同じコード」という理由で共通化すると、 片方の都合(コスト削減)で、もう片方の資産(データ)を破壊してしまう可能性ある
  18. Copyright © 3-shake, Inc. All Rights Reserved. 改めて考えると良くない 24 S3いっぱい使うから毎回書くの良くないな…

    よし!module作るぞ! # env/dev/main.tf module "log_bucket" { source = "./modules/s3" bucket_name = "my-log-bucket" } module "data_bucket" { source = "./modules/s3" bucket_name = "my-data-bucket" }
  19. Copyright © 3-shake, Inc. All Rights Reserved. 抽象化をする 26 "A

    good module should raise the level of abstraction by describing a new concept in your architecture that is constructed from resource types offered by providers." 優れたモジュールは、プロバイダが提供するリソースタイプから構成されるアーキテクチャにおける新しい概念を定義すること で、抽象化のレベルを引き上げるべきである。 — Terraform 公式ドキュメント "When to write a module" [3] Log用のs3 • 監査・アクセスログを保存する • 改ざん不可・長期保存が前提 • 変更要件はガバナンス依存 aws_s3_bucket bucket_policy lifecycle 新しい概念を定義
  20. Copyright © 3-shake, Inc. All Rights Reserved. 抽象化をする 27 •

    概念を定義することでそのmoduleが何のた めにあるかが決まる • 何が必要で何が不要かの判断基準ができる ラベリングされる • コードを読まなくても表す概念がわかる 目的や責務が決まる
  21. Copyright © 3-shake, Inc. All Rights Reserved. では、その概念を誰のために定義するのか? 28 •

    インフラに詳しい • モジュールを使う・管理 • インフラ構成は自分で作る SRE・インフラ • インフラは専門外 • モジュールを使うだけ • インフラ構成は作って欲しい フロント・バック・DS 利用者も作者も嬉しいモジュール 利用者に嬉しいモジュール
  22. Copyright © 3-shake, Inc. All Rights Reserved. では、その概念を誰のために定義するのか? 29 •

    インフラに詳しい • モジュールを使う・管理 • インフラ構成は自分で作る SRE・インフラ • インフラは専門外 • モジュールを使うだけ • インフラ構成は作って欲しい フロント・バック・DS 利用者も作者も嬉しいモジュール 利用者に嬉しいモジュール ここが大事 ここが大事
  23. Copyright © 3-shake, Inc. All Rights Reserved. 利用するユーザを考えた設計 30 ターゲット:SRE→SRE(管理も利用する)

    自分たちのコードを整理するため。リソースの配 置や依存関係(構成)を綺麗にまとめる共通化 SREが組み合わせて使う「パーツ」だからこ そ、魔境化しないでシンプルに保つ。 ブラックボックス・カプセル化(隠蔽) ターゲット:SRE→アプリ(利用だけする) インフラを意識させないため。「セキュアなログ 保存」「Webサイト公開」という機能そのものを 届けるためのカプセル化 アプリ開発者に「価値」だけを届けるために、 裏側の複雑性を引き受ける。 ホワイトボックス・テンプレート(共通化)
  24. Copyright © 3-shake, Inc. All Rights Reserved. 利用するユーザを考えた設計 31 ターゲット:SRE→SRE(管理も利用する)

    自分たちのコードを整理するため。リソースの配 置や依存関係(構成)を綺麗にまとめる共通化 SREが組み合わせて使う「パーツ」だからこ そ、魔境化しないでシンプルに保つ。 ブラックボックス・カプセル化(隠蔽) ターゲット:SRE→アプリ(利用だけする) インフラを意識させないため。「セキュアなログ 保存」「Webサイト公開」という機能そのものを 届けるためのカプセル化 アプリ開発者に「価値」だけを届けるために、 裏側の複雑性を引き受ける。 ホワイトボックス・テンプレート(共通化) 魔境化させない 魔境化を受け入れる
  25. Copyright © 3-shake, Inc. All Rights Reserved. ホワイトボックス:「構成」の抽象化は魔境化させない 32 moduleが決めるもの

    • リソース構成や依存関係 • ドメイン特有の定石・お作法等の設定 ユーザに委ねるもの • 意思決定が必要な値 • どこで・どう組み合わせて使うか module "app_log" { source = "./modules/log_s3" # どう使うか?(app?aws_audit?) bucket_name = "app_log" # 意思決定が必要な値 retention_days = 90 storage_class = "GLACIER" }
  26. Copyright © 3-shake, Inc. All Rights Reserved. ホワイトボックス:「構成」の抽象化は魔境化させない 33 知識の集約

    • ドメイン特有の設定値等を強制 • 変更を安全かつ即座に全体へ波及させる コードの認知負荷の低減 • 実装の詳細を「論理的なグループ」に置換 • 「正しく書く」ための労力を、アーキテク チャ上の「意思決定」のみに集中 利用者 管理者
  27. Copyright © 3-shake, Inc. All Rights Reserved. ブラックボックス:「機能」の抽象化は魔境化を受け入れる 34 moduleが決めるもの

    • 変数に応じた最適なリソース構成 • 変数に応じた最適なリソースの設定 ユーザに委ねるもの • 「何を実現したいか」という目的の入力 • ビジネス上の要求レベル ◦ 具体的な手段は委ねない module "app_log" { source = "./modules/log_platform" # 目的や意図だけを出す # 何を入れるか(app,alb,db,aws_audit) log_source = "app" }
  28. Copyright © 3-shake, Inc. All Rights Reserved. ブラックボックス:「機能」の抽象化は魔境化を受け入れる 35 ガバナンスと標準化の強制

    • セキュリティや可用性設計はモジュールが自 動的に最適化する。 • 利用者を「サービスを動かすこと」に全集中 できるようにする 専門外の認知負荷を限りなく減らす • 実装の詳細を「単一の機能」に置換 • 具体的なリソースを意識させない 利用者 管理者
  29. Copyright © 3-shake, Inc. All Rights Reserved. ホワイトボックスの場合:ドメインの「標準部品」を定義する 37 SRE/インフラ担当者

    プロジェクト全体の構成を把握し、各リソースの ライフサイクルの違いを理解しているインフラに 詳しく、責任が持てる層 どんな概念か? 「計算機+IAM+ログ」の最小単位 汎用的なECSやCloud Runを、プロジェクトの規 約に沿った「api-svc標準部品」として定義する 誰が利用するか?
  30. Copyright © 3-shake, Inc. All Rights Reserved. ホワイトボックス:ユーザーに「委ねる」設計 38 module

    "user_api" { source = "./modules/api/svc" # 1. 意思決定(コスト・スペック) cpu = 512 memory = 1024 # 2. 配線(どこで・どう組み合わせるか) iam_policy_arns = ["arn:xxx:xxx:" ] sg_rules = ["sg-xxxx"] } Ecs module どこで・どう組み合わせて使うか • 外部リソースの接続に必要な値を露出させる • 変則的な構成変更にも柔軟に対応できる疎結 合なインターフェースを維持する。 意思決定が必要な値 • 意思決定が必要な値を露出させる • コストや運用方針に関わるパラメータはモ ジュールが決め打ちせず、利用者に委ねる。
  31. Copyright © 3-shake, Inc. All Rights Reserved. ブラックボックスの場合:ドメインの「プラットフォーム」を定義する 39 アプリケーション開発者

    インフラの詳細は意識せず、セルフサービスで迅 速にAPIを公開したい層 どんな概念か? 「APIサービス実行環境」そのもの 計算機だけでなく、通信経路や付随するセキュリ ティ設定までを一つの機能として定義 誰が利用するか?
  32. Copyright © 3-shake, Inc. All Rights Reserved. ブラックボックス:ユーザーに「委ねる」設計 40 module

    "user_api" { source = "./modules/api/svc" # 1. 目的:インフラの「形」を決定 visibility = "internal" db_usage = "shared" service_name = "payment-api" # 2. 要求レベル:パラメータの「質」を決定 resiliency = "high" # 冗長化の要 否 data_sensitivity = "pii" # データの機 密 } ビジネス上の要求レベル • 冗長構成の要否や、データの機密度といった 「要求水準」を入力させる • 入力された値に基づき、モジュールが自動適 用する。 「何を実現したいか」という目的 • 公開範囲や接続先など、ドメインの意図だけを 入力させる • 具体的なリソースを隠蔽し、利用者の認知負荷 を極限まで下げる。
  33. Copyright © 3-shake, Inc. All Rights Reserved. 魔境化に向かう2つのパターン 43 SREが管理しやすいはずの「透明なモジュー

    ル」を作ろうとしたが、知識(ライフサイク ル)が違うものを無理に共通化した結果、変数 やロジックが大量な魔境になる。 ホワイトボックスの失敗 =「間違ったDRY」 アプリ開発者が詳細を意識しなくていいよう に、インフラの構築ロジックをすべてモジュー ル内部にカプセル化する。 ブラックボックスの目的 =「高い抽象度」
  34. Copyright © 3-shake, Inc. All Rights Reserved. 魔境との付き合い方・向き合い方 44 対象:同じチームでモジュールの利用・管理

    • 知識(ライフサイクル)ごとにモジュー ルを適切に分離し、シンプルさを保つ。 • 利用者だけでなく、管理者の認知負荷も 考えて作る 魔境化させては「いけない」ケース 対象:モジュールの利用・管理が別チーム • 利用者の優れたUX(認知負荷の極小 化)を考えて作る • モジュール提供側が「魔境の複雑さ」を 背負い、責任を持って管理し続ける。 魔境化を「受け入れる」べきケース 「魔境化」は一概に悪ではない。「誰が管理し、誰が使うか」で割り切りを変える。
  35. [1] David Thomas, Andrew Hunt 著, 村上 雅章 訳『達人プログラマー』p.96 (Kindle版)

    [2] Gosuke Miyashita「なぜインフラコードのモジュール化は難しいのか — アプリケーションコードとの本質的な違いから考える」 https://speakerdeck.com/mizzy/yapc-fukuoka-2025 [3] HashiCorp "Creating Modules — When to write a module" https://developer.hashicorp.com/terraform/language/modules/develop#when-to-write-a-m odule Copyright © 3-shake, Inc. All Rights Reserved. 参考資料・文献 45