Share
Embed
Transcript
47 slides
-
Terraformモジュールは、なぜ「魔境」化するのか Copyright © 3-shake, Inc. All Rights Reserved. 1 クラウドネイティブ会議
day2 - 2026年5月15日 羽山 公平(hymaaa_k) -
Copyright © 3-shake, Inc. All Rights Reserved. 今回の登壇で話すこと、話さないこと 3 •
なぜ魔境化するのか • 魔境化との向き合い方 話さないこと • 既にある魔境の綺麗にする方法 話すこと これから綺麗に作るぞ!という方、なんで使いづらくなるんだろ?と疑問を持っている方むけ -
Copyright © 3-shake, Inc. All Rights Reserved. 自己紹介 4 羽山
公平 Sreak事業部で、主にAWSやGCP等のクラウド環 境でのSREをしております。 最近では、AIREといったAI+SREといった領域を 調べています!! @hymaaa_k -
会社紹介 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) -
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の処理を読まないと何が作られるのか分からない状態のこと -
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" { ... } … -
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" } -
Copyright © 3-shake, Inc. All Rights Reserved. なぜ生まれるの? 10 S3でlog貯めるなら、
ライフサイクルは設定し てください S3でコンテンツ配信し たいから、 バージョニングしたい -
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 } # ... 要件に合わせて変数が増える -
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 ... } -
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 } -
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 個近くある } -
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" } -
Copyright © 3-shake, Inc. All Rights Reserved. DRY原則 18 DRY原則とは「コードを重複させるな」ではなく「知識を重複させるな」という原則
すべての知識はシステム内において、単一、かつ明確な、 そして信頼できる表現になっていなければならない。 — Hunt & Thomas『達人プログラマー』DRY原則 [1] -
Copyright © 3-shake, Inc. All Rights Reserved. アプリのコードとTerraformのコードの違い 19 •
処理を記述 • 「誰が・何のために使うか(文脈)」に依存❌ ◦ ex)ソートの処理はどこでも同じ ▪ Logの検索 ▪ フロントエンドの描写 Terraformのコード • 状態を記述 • 「誰が・何のために使うか(文脈)」に依存 ◦ ex) s3は用途によって違う ▪ Log用のs3 ▪ コンテンツのs3 アプリのコード アプリケーションコードは「処理」を記述する。 Terraformコードは「状態」を記述する。 — Gosuke Miyashita「なぜインフラコードのモジュール化は難しいのか」 YAPC::Fukuoka 2025 [2] -
Copyright © 3-shake, Inc. All Rights Reserved. アプリコードにおけるDRY 20 item_sort
user_sort log_sort 共通するsortする処理 コード 切り抜いて DRY達成 処理を記述 def sort(list, key) 知識の単一化=DRY達成 切り抜いたある処理は 処理だけを使いまわせる -
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 インフラリソースには文脈があ るので文脈ごとにグループ化 -
Copyright © 3-shake, Inc. All Rights Reserved. 同じ S3 だけど、「知識」は違う
22 目的 :監査・デバッグ データの性質 :一定期間で価値が低下 削除保護 :不要(コスト優先で消す) アクセス制限 :管理者のみ ライフサイクル : x日で削除・安価なストレージへ ログ用のS3 目的 :ビジネス継続・収益 データの性質 :長期間に渡り高い価値を持つ 削除保護 :必須(事故=事業停止) アクセス制限 :細かい(個人情報・機密情報) ライフサイクル : 原則永久保持 or 長期保管 データ用のS3 「同じリソース」や「同じコード」という理由で共通化すると、 片方の都合(コスト削減)で、もう片方の資産(データ)を破壊してしまう可能性ある -
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" } -
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 新しい概念を定義 -
Copyright © 3-shake, Inc. All Rights Reserved. 抽象化をする 27 •
概念を定義することでそのmoduleが何のた めにあるかが決まる • 何が必要で何が不要かの判断基準ができる ラベリングされる • コードを読まなくても表す概念がわかる 目的や責務が決まる -
Copyright © 3-shake, Inc. All Rights Reserved. では、その概念を誰のために定義するのか? 28 •
インフラに詳しい • モジュールを使う・管理 • インフラ構成は自分で作る SRE・インフラ • インフラは専門外 • モジュールを使うだけ • インフラ構成は作って欲しい フロント・バック・DS 利用者も作者も嬉しいモジュール 利用者に嬉しいモジュール -
Copyright © 3-shake, Inc. All Rights Reserved. では、その概念を誰のために定義するのか? 29 •
インフラに詳しい • モジュールを使う・管理 • インフラ構成は自分で作る SRE・インフラ • インフラは専門外 • モジュールを使うだけ • インフラ構成は作って欲しい フロント・バック・DS 利用者も作者も嬉しいモジュール 利用者に嬉しいモジュール ここが大事 ここが大事 -
Copyright © 3-shake, Inc. All Rights Reserved. 利用するユーザを考えた設計 30 ターゲット:SRE→SRE(管理も利用する)
自分たちのコードを整理するため。リソースの配 置や依存関係(構成)を綺麗にまとめる共通化 SREが組み合わせて使う「パーツ」だからこ そ、魔境化しないでシンプルに保つ。 ブラックボックス・カプセル化(隠蔽) ターゲット:SRE→アプリ(利用だけする) インフラを意識させないため。「セキュアなログ 保存」「Webサイト公開」という機能そのものを 届けるためのカプセル化 アプリ開発者に「価値」だけを届けるために、 裏側の複雑性を引き受ける。 ホワイトボックス・テンプレート(共通化) -
Copyright © 3-shake, Inc. All Rights Reserved. 利用するユーザを考えた設計 31 ターゲット:SRE→SRE(管理も利用する)
自分たちのコードを整理するため。リソースの配 置や依存関係(構成)を綺麗にまとめる共通化 SREが組み合わせて使う「パーツ」だからこ そ、魔境化しないでシンプルに保つ。 ブラックボックス・カプセル化(隠蔽) ターゲット:SRE→アプリ(利用だけする) インフラを意識させないため。「セキュアなログ 保存」「Webサイト公開」という機能そのものを 届けるためのカプセル化 アプリ開発者に「価値」だけを届けるために、 裏側の複雑性を引き受ける。 ホワイトボックス・テンプレート(共通化) 魔境化させない 魔境化を受け入れる -
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" } -
Copyright © 3-shake, Inc. All Rights Reserved. ホワイトボックス:「構成」の抽象化は魔境化させない 33 知識の集約
• ドメイン特有の設定値等を強制 • 変更を安全かつ即座に全体へ波及させる コードの認知負荷の低減 • 実装の詳細を「論理的なグループ」に置換 • 「正しく書く」ための労力を、アーキテク チャ上の「意思決定」のみに集中 利用者 管理者 -
Copyright © 3-shake, Inc. All Rights Reserved. ブラックボックス:「機能」の抽象化は魔境化を受け入れる 34 moduleが決めるもの
• 変数に応じた最適なリソース構成 • 変数に応じた最適なリソースの設定 ユーザに委ねるもの • 「何を実現したいか」という目的の入力 • ビジネス上の要求レベル ◦ 具体的な手段は委ねない module "app_log" { source = "./modules/log_platform" # 目的や意図だけを出す # 何を入れるか(app,alb,db,aws_audit) log_source = "app" } -
Copyright © 3-shake, Inc. All Rights Reserved. ブラックボックス:「機能」の抽象化は魔境化を受け入れる 35 ガバナンスと標準化の強制
• セキュリティや可用性設計はモジュールが自 動的に最適化する。 • 利用者を「サービスを動かすこと」に全集中 できるようにする 専門外の認知負荷を限りなく減らす • 実装の詳細を「単一の機能」に置換 • 具体的なリソースを意識させない 利用者 管理者 -
Copyright © 3-shake, Inc. All Rights Reserved. ホワイトボックスの場合:ドメインの「標準部品」を定義する 37 SRE/インフラ担当者
プロジェクト全体の構成を把握し、各リソースの ライフサイクルの違いを理解しているインフラに 詳しく、責任が持てる層 どんな概念か? 「計算機+IAM+ログ」の最小単位 汎用的なECSやCloud Runを、プロジェクトの規 約に沿った「api-svc標準部品」として定義する 誰が利用するか? -
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 どこで・どう組み合わせて使うか • 外部リソースの接続に必要な値を露出させる • 変則的な構成変更にも柔軟に対応できる疎結 合なインターフェースを維持する。 意思決定が必要な値 • 意思決定が必要な値を露出させる • コストや運用方針に関わるパラメータはモ ジュールが決め打ちせず、利用者に委ねる。 -
Copyright © 3-shake, Inc. All Rights Reserved. ブラックボックスの場合:ドメインの「プラットフォーム」を定義する 39 アプリケーション開発者
インフラの詳細は意識せず、セルフサービスで迅 速にAPIを公開したい層 どんな概念か? 「APIサービス実行環境」そのもの 計算機だけでなく、通信経路や付随するセキュリ ティ設定までを一つの機能として定義 誰が利用するか? -
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" # データの機 密 } ビジネス上の要求レベル • 冗長構成の要否や、データの機密度といった 「要求水準」を入力させる • 入力された値に基づき、モジュールが自動適 用する。 「何を実現したいか」という目的 • 公開範囲や接続先など、ドメインの意図だけを 入力させる • 具体的なリソースを隠蔽し、利用者の認知負荷 を極限まで下げる。 -
Copyright © 3-shake, Inc. All Rights Reserved. 魔境化に向かう2つのパターン 43 SREが管理しやすいはずの「透明なモジュー
ル」を作ろうとしたが、知識(ライフサイク ル)が違うものを無理に共通化した結果、変数 やロジックが大量な魔境になる。 ホワイトボックスの失敗 =「間違ったDRY」 アプリ開発者が詳細を意識しなくていいよう に、インフラの構築ロジックをすべてモジュー ル内部にカプセル化する。 ブラックボックスの目的 =「高い抽象度」 -
Copyright © 3-shake, Inc. All Rights Reserved. 魔境との付き合い方・向き合い方 44 対象:同じチームでモジュールの利用・管理
• 知識(ライフサイクル)ごとにモジュー ルを適切に分離し、シンプルさを保つ。 • 利用者だけでなく、管理者の認知負荷も 考えて作る 魔境化させては「いけない」ケース 対象:モジュールの利用・管理が別チーム • 利用者の優れたUX(認知負荷の極小 化)を考えて作る • モジュール提供側が「魔境の複雑さ」を 背負い、責任を持って管理し続ける。 魔境化を「受け入れる」べきケース 「魔境化」は一概に悪ではない。「誰が管理し、誰が使うか」で割り切りを変える。 -
[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