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

なぜインフラコードのモジュール化は難しいのか - アプリケーションコードとの本質的な違いから考える

なぜインフラコードのモジュール化は難しいのか - アプリケーションコードとの本質的な違いから考える

Avatar for Gosuke Miyashita

Gosuke Miyashita

November 14, 2025
Tweet

More Decks by Gosuke Miyashita

Other Decks in Technology

Transcript

  1. YAPC::Fukuoka 2025 宮下 剛輔 合同会社Serverspec Operations代表社員 フリーランス ソフトウェアエンジニア  mizzy.org /

     mizzy /  gosukenator YAPC 10年ぶり11回目 参加 13年ぶり8回目 トーク(前夜祭、LTソン含む)
  2. YAPC::Fukuoka 2025 本発表 趣旨 • インフラコード モジュール化 難しい ◦ アプリケーションコードと同じ感覚で

    うまくいかない ◦ 適切なモジュール化/モジュールを活用した運用が難しい • なぜ難しい か、そ 理由を言語化したい ◦ 既存 資料で 十分に語られていない • 難しさとどう向き合うべきかを考える ◦ 難しさ 理由がわかれ 、向き合い方も見えてくる で • 具体的なIaCツールとしてTerraformを扱います • 多く 考え方 他 IaCツールにも適用できますが、すべてに当て まると 限りません
  3. YAPC::Fukuoka 2025 モジュールという用語について • こ 発表で 、役割や責務でまとまった単位を総称して「モジュール」と呼 びます • 言語やツールごとにライブラリ、パッケージ、チャート(例:

    Kubernetes Helm)など呼び方 異なりますが、議論を単純化するために共通語として モジュールという言葉を用います • ファイルやディレクトリに分割することも広義 モジュール化として扱いま す
  4. YAPC::Fukuoka 2025 Table of contents 01 02 04 05 03

    06 インフラコード モジュール化 難しさ 利用 しかた 抽象化 目的 記述 対象 設計へ 影響 難しさと どう向き合うか 状態を記述するインフラコード vs 処理を記述するアプリケーショ ンコード 構成 パターン化 vs 処理 カプセル化 ホワイトボックス的利用 vs ブラックボックス的利用 内部構造 可視性 vs 抽象性・ 階層化
  5. YAPC::Fukuoka 2025 Terraformモジュール 具体的な問題点 • インフラコード固有で ない問題(本発表で 扱わない) ◦ メンテされない

    ◦ 互換性を壊す • インフラコードで顕著な問題 ◦ まとめすぎ ◦ 細分化しすぎ ◦ アプリケーションコードで 悪い設計とされる ◦ しかしインフラコードで 有名モジュールでさえまかり通っている
  6. YAPC::Fukuoka 2025 terraform-aws-vpcモジュール • 定義されている変数 236個 ◦ すべてオプショナル • 扱っているリソースタイプ

    種類 32種類 ◦ main.tf: 27種類 ◦ vpc-flow-logs.tf: 5種類(VPC Flow Logs関連 リソース) • 最小構成 4種類/4個 リソース • 最大構成 32種類/118個 リソース 本スライド 数字 v6.4.0(2025年10月時点 最新版) も
  7. YAPC::Fukuoka 2025 terraform-aws-vpcモジュールで扱うリソースタイプ aws_cloudwatch_log_group aws_customer_gateway aws_db_subnet_group aws_default_network_acl aws_default_route_table aws_default_security_group aws_default_vpc

    aws_egress_only_internet_gateway aws_eip aws_elasticache_subnet_group aws_flow_log aws_iam_policy aws_iam_role aws_iam_role_policy_attachment aws_internet_gateway aws_nat_gateway aws_network_acl aws_network_acl_rule aws_redshift_subnet_group aws_route aws_route_table aws_route_table_association aws_subnet aws_vpc aws_vpc_block_public_access_exclusion aws_vpc_block_public_access_options aws_vpc_dhcp_options aws_vpc_dhcp_options_association aws_vpc_ipv4_cidr_block_association aws_vpn_gateway aws_vpn_gateway_attachment aws_vpn_gateway_route_propagation
  8. YAPC::Fukuoka 2025 VPC コア機能と 関連が薄いリソースタイプ • VPC Flow Logs関連 ◦

    aws_iam_policy ◦ aws_iam_role ◦ aws_iam_role_policy_attachment ◦ aws_cloudwatch_log_group • VPN関連 ◦ aws_customer_gateway ◦ aws_vpn_gateway ◦ aws_vpn_gateway_route_propagation • 特定サービス用サブネットグループ ◦ aws_db_subnet_group ◦ aws_elasticache_subnet_group ◦ aws_redshift_subnet_group
  9. YAPC::Fukuoka 2025 terraform-aws-vpcモジュール 問題 • まとめすぎ ◦ VPC関連であれ なんでも詰め込む ◦

    機能的な関連性で なく、分類的な関連性でまとめている ◦ コア機能と周辺機能が混在 ▪ Flow Logs、VPN、サブネットグループなど • 結果として生じる問題 ◦ 236個 変数:内部構造がそ まま露出 ◦ 1542行 main.tf:全体像 把握が不可能
  10. YAPC::Fukuoka 2025 サブモジュールで扱うリソース 種類 • modules/vpc: 2種類 ◦ google_compute_network ◦

    google_compute_shared_vpc_host_project • modules/subnets: 1種類 ◦ google_compute_subnetwork • modules/routes: 1種類 ◦ google_compute_route • modules/firewall-rules: 1種類 ◦ google_compute_firewall
  11. YAPC::Fukuoka 2025 過度な細分化 • 各サブモジュールが1〜2種類 リソースしか扱っていない • VPC、サブネット、ルート、ファイアウォール 密接に関連 ◦

    通常 セットで設計・管理するリソース群 ◦ これらを分離することで、かえって全体像が把握しにくくなっている
  12. YAPC::Fukuoka 2025 terraform-google-networkモジュール 問題 • 細分化しすぎ ◦ 過度に細分化:各サブモジュールが1〜2種類 リソース み

    ◦ 本来一緒に管理すべきリソース 分離 ▪ VPC、サブネット、ルート、ファイアウォール • 結果として生じる問題 ◦ 本来一緒にあるべきリソースが分離され、全体像が把握しにくくなる
  13. YAPC::Fukuoka 2025 多段構成による問題 悪化 • terraform-google-network 2段階構成 ◦ メインモジュール →

    サブモジュール ◦ 既に「細分化しすぎ」と「まとめすぎ」が同時に存在 ▪ 細分化しすぎ:サブモジュールが過度に分割されている ▪ まとめすぎ:メインから呼 れないサブモジュールも含まれる • さらに階層が深くなる例も存在 ◦ 3段階以上 構成 ◦ 問題がより複雑化・深刻化
  14. YAPC::Fukuoka 2025 多段構成 例 : terraform-google-project-factory* • 3段階 モジュール階層 ◦

    Level 1(メインモジュール): 複数 サブモジュールを呼び出し ◦ Level 2(core_project_factory): プロジェクト コア機能を管理 ◦ Level 3(project_services): API有効化とサービスアイデンティティ管 理 * https://github.com/terraform-google-modules/terraform-google-project-factory
  15. YAPC::Fukuoka 2025 terraform-google-project-factory 問題 点 • まとめすぎ ◦ プロジェクト作成 コア機能とオプショナルな機能が混在

    ◦ Shared VPC、Storage、Budgetなど多様なリソースを含む • 細分化しすぎ ◦ core_project_factoryがproject_servicesに依存 ◦ 一緒にいるべきも が階層で分断されている • 「まとめすぎ」と「細分化しすぎ」が同時に存在 ◦ 結果として全体像 把握が困難になり、依存関係 追跡も複雑化
  16. YAPC::Fukuoka 2025 多段構成による問題 悪化 • 2段構成から既に問題が発生 ◦ terraform-google-network: 「まとめすぎ」と「細分化しすぎ」が同時に 存在

    ◦ 全体像 把握が困難 • 3段構成以上で さらに複雑化・深刻化 ◦ terraform-google-project-factory: 複数 階層に問題が広がる ◦ 全体像 把握と依存関係 追跡がより困難 • 階層が深くなるほど、内部構造 可視性が損なわれる
  17. YAPC::Fukuoka 2025 凝集度* • 偶発的凝集(最悪、凝集度が低い) • 論理的凝集 • 時間的凝集 •

    手続き的凝集 • 通信的凝集 • 逐次的凝集 • 機能的凝集(最良、凝集度が高い) *Yourdon, E., & Constantine, L. L. (1979). Structured Design: Fundamentals of a Discipline of Computer Program and Systems Design. Prentice-Hall.
  18. YAPC::Fukuoka 2025 結合度* • 内容結合(最悪、結合度が高い) • 共通結合 • 外部結合 •

    制御結合 • スタンプ結合 • データ結合 • メッセージ結合(最良、結合度が低い) *Yourdon, E., & Constantine, L. L. (1979). Structured Design: Fundamentals of a Discipline of Computer Program and Systems Design. Prentice-Hall.
  19. YAPC::Fukuoka 2025 凝集度と結合度で見た問題 • まとめすぎ ◦ terraform-aws-vpcモジュール 関連しそうなリソースをひとつ モ ジュールにまとめている

    ◦ 凝集度が低い状態(論理的凝集) • 細分化しすぎ ◦ terraform-google-networkモジュール リソースが過度に細分化さ れている ◦ 親モジュールが変数で子モジュール 構成を制御する必要がある ◦ 結合度が高い状態(制御結合) • 多段構成による問題 悪化 ◦ terraform-google-project-factoryモジュール ◦ 凝集度 低さ・結合度 高さが同時に存在し、さらに複雑化
  20. YAPC::Fukuoka 2025 コナーセンス * • 2つ モジュール間 変更に関する依存関係 • 一方

    変更が他方 対応する変更を必要とする • 構造化設計におけるモジュール結合よりも詳細なモデル ◦ 知識 共有 され方を詳細に分類 ◦ 静的コナーセンス: コンパイル時 関係 ◦ 動的コナーセンス: 実行時 関係 *Page-Jones, M. (1996). What Every Programmer Should Know About Object-Oriented Design. Dorset House.
  21. YAPC::Fukuoka 2025 コナーセンス • 静的コナーセンス ◦ CoN (Name) - 名前

    一致 ◦ CoT (Type) - 型 一致 ◦ CoM (Meaning) - 値 意味 一致 ◦ CoP (Position) - 位置 一致 ◦ CoA (Algorithm) - アルゴリズム 一致 • 動的コナーセンス(静的より強い結合) ◦ CoE (Execution) - 実行順序 ◦ CoT (Timing) - タイミング ◦ CoV (Value) - 値 ◦ CoI (Identity) - 同一性
  22. YAPC::Fukuoka 2025 コナーセンスで 分析 限界 • コナーセンスで 分析を試みたが... ◦ terraform-aws-vpc:

    静的コナーセンス(CoN, CoT)が極端に多い ◦ terraform-google-network: 基本的な静的コナーセンス(CoN, CoT) • こ ケースで 凝集度・結合度 概念 方が問題 本質を捉えやすい ◦ コナーセンス 依存関係 詳細な分類に 有効 ◦ しかし構造的な問題(論理的凝集など) 説明に 凝集度 方が直 感的
  23. YAPC::Fukuoka 2025 統合強度* • 構造化設計 モジュール結合とコナーセン ス、両方 エッセンスを取り入れた新しい統 合モデル •

    境界を越えて共有される知識 種類や性質 に基づいて結合を評価 *Khononov, V. (2024). Balancing Coupling in Software Design. Addison-Wesley. (邦訳: ソフトウェア設計 結合バラ ンス, インプレス, 2025)
  24. YAPC::Fukuoka 2025 統合強度 • 侵入結合(Intrusive coupling) ◦ 実装詳細へ 依存 ◦

    最も強い結合 • 機能結合(Functional coupling) ◦ ビジネスロジック 共有 • モデル結合(Model coupling) ◦ データモデル 共有 • コントラクト結合(Contract coupling) ◦ 統合専用 インターフェース ◦ 最も弱い結合
  25. YAPC::Fukuoka 2025 統合強度で見た問題 • terraform-aws-vpc(まとめすぎ) ◦ 236個 変数を公開し、内部モデルをそ まま共有(モデル結合) ◦

    浅いモジュール*:複雑性をカプセル化できていない ◦ 漏れ ある抽象化 • terraform-google-network(細分化しすぎ) ◦ 機能結合: 親が変数で子 構成を制御 • terraform-google-project-factory(多段構成) ◦ モデル結合と機能結合が複合的に存在 *Ousterhout, J. (2018). A Philosophy of Software Design. Yaknyam Press. 浅いモジュール:公開インターフェースと実 装 差が小さいモジュール
  26. YAPC::Fukuoka 2025 01 インフラコードモジュール化 難しさ まとめ • 有名なパブリックモジュールによく見られる凝集度・結合度 問題 ◦

    論理的凝集(terraform-aws-vpc) ◦ 制御結合(terraform-google-network) • 多段構成が問題をさらに悪化させる ◦ 2段構成で論理的凝集・制御結合が発生しうる ◦ 3段構成で これら 問題がより深刻化・複雑化 • アプリケーションコードで 悪い設計として認識される ◦ インフラコードで これがまかり通っている • 次章以降で 、なぜ論理的凝集・制御結合がインフラコードで起きやすい かを考える
  27. YAPC::Fukuoka 2025 なぜインフラコードで凝集度・結合度 問題が起きやすい か • 1章で見たような問題 アプリケーションコードで 悪い設計として認識され る

    • なぜインフラコードで 「まかり通っている」 か? • インフラコードとアプリケーションコード 違いに起因してそう
  28. YAPC::Fukuoka 2025 根本的な違い : 状態 記述 vs 処理 記述 •

    インフラコード 「状態」を記述する ◦ リソース 詳細が主眼 • アプリケーションコード 「処理」を記述する ◦ 処理 役割が主眼
  29. YAPC::Fukuoka 2025 特徴 比較 : 記述内容 • 「VPC」「パブリックサブネット」「プライベートサブネット」 あるべき状態を宣 言

    • リソース 状態を宣言し、依存関係を記述する インフラコード アプリケーションコード • 「ユーザー検索」 → 「認証」 → 「セッション生成」といった手順を記述 • 処理 流れと呼び出し関係を記述する
  30. YAPC::Fukuoka 2025 特徴 比較 : 関心事 • VPCやサブネット 設定内容(CIDRブロック、DNS設定、AZ、Nameタグな ど)

    • リソース 詳細な設定内容が関心事 インフラコード アプリケーションコード • ユーザー検索、認証、セッション生成 • 処理 役割が関心事で、実装 詳細 関心外
  31. YAPC::Fukuoka 2025 特徴 比較 : 抽象化 しやすさ • リソース 詳細な内容や依存関係が関心事

    • 抽象化して隠蔽すると実際 設定内容や依存関係が見えなくなる • 抽象化できる範囲が限定的 インフラコード アプリケーションコード • 実装 詳細 関心外 • 抽象化して隠蔽しても、処理 流れが理解できれ よい • 広い範囲で抽象化でき、実装 詳細を隠蔽できる
  32. YAPC::Fukuoka 2025 02 記述 対象 まとめ • インフラコードとアプリケーションコード 根本的な違い ◦

    インフラコード:状態を記述する ◦ アプリケーションコード:処理を記述する • こ 違いが関心事 違いを生む ◦ インフラコード:リソース 詳細な設定内容が関心事 ◦ アプリケーションコード:処理が何をするかが関心事 • 関心事 違い 抽象化 しやすさに影響する ◦ インフラコード:詳細を隠せない → 抽象化しにくい ◦ アプリケーションコード:詳細を隠せる → 抽象化しやすい • 次章以降で 、こ 違いが抽象化 目的やモジュール 利用 しかたに どう影響するかを考える
  33. YAPC::Fukuoka 2025 関心事 違いが抽象化 目的を決める • 2章で見た関心事 違い ◦ インフラコード:リソース

    詳細な設定内容が関心事 ◦ アプリケーションコード:処理が何をするかが関心事 • 抽象化 目的 ◦ インフラコード:詳細が関心事 → 構成 パターン化 ◦ アプリケーションコード:処理が何をするかが関心事 → 処理 カプセ ル化
  34. YAPC::Fukuoka 2025 インフラコード 抽象化 目的 • 詳細が関心事な で、実装 詳細 隠蔽できない

    ◦ 設定 詳細や依存関係 見えている必要がある ◦ な で抽象化しにくい • で 何 ために抽象化する か? ◦ 構成 パターンを再利用するため ▪ 構成パターンをテンプレート化して使い回す ▪ セキュリティ ベストプラクティスを組み込む ▪ 組織 標準設定を適用する • 例:3-AZ構成 VPC ◦ パブリックサブネット×3、プライベートサブネット×3、NATゲートウェイ×3 ◦ こ 「パターン」をすべて 環境に適用したい
  35. YAPC::Fukuoka 2025 アプリケーションコード 抽象化 目的 • 処理が何をするかが関心事な で、実装 詳細 隠蔽できる

    ◦ な で抽象化しやすい • 抽象化することで何が実現できるか? ◦ 本質的な処理に集中できる ◦ 実装変更を容易にする ◦ 変更 影響範囲を限定する ◦ コードを再利用可能にする
  36. YAPC::Fukuoka 2025 03 抽象化 目的 まとめ • 関心事 違いが抽象化 目的を決める

    ◦ インフラコード:詳細が関心事 → 構成 パターン化 ◦ アプリケーションコード:処理が何をするかが関心事 → 処理 カプセル化 • インフラコード 構成 パターンを再利用する ◦ 詳細を隠蔽できないため、パターンをテンプレート化して使い回す ◦ セキュリティ ベストプラクティスや組織 標準設定を適用する • アプリケーションコード 処理をカプセル化する ◦ 詳細を隠蔽して、本質的な処理に集中できるようにする ◦ 実装変更を容易にし、変更 影響範囲を限定する • 次章で 、こ 違いがモジュール 利用 しかたにどう影響するかを考える
  37. YAPC::Fukuoka 2025 抽象化 しやすさ 違いが利用 しかたに影響 • 2章で見た関心事 違い 、抽象化

    しやすさも決める ◦ インフラコード:詳細が関心事 → 詳細を隠せない ◦ アプリケーションコード:処理が何をするかが関心事 → 詳細を隠せる • 抽象化 しやすさ 違い 、モジュール 利用 しかたに影響する ◦ インフラコード:モジュール 中身を理解して使う必要がある ◦ アプリケーションコード:モジュール 中身を知らなくても使える • モジュール 使い方 ◦ インフラコード:ホワイトボックス的利用 (中身を理解して使う) ◦ アプリケーションコード:ブラックボックス的利用 (中身を知らずに使え る)
  38. YAPC::Fukuoka 2025 インフラコード:ホワイトボックス的利用 • モジュール 中身を理解して使う必要がある ◦ どんなリソースが作られるか ◦ どういう依存関係になるか

    ◦ どんな設定が可能か • モジュール 全容が把握しやすい必要がある ◦ コードを読め 理解できる ◦ ドキュメントで構成内容が把握できる ◦ 要件に過不足 ない構成(内容が推測しやすい) ◦ 合意形成を通じた共通理解 形成 • パブリックなモジュールをそ まま使う 難しい ◦ 要件に完全に合致するモジュール 少ない ◦ 組織内で管理されたモジュールを使うか、自作する
  39. YAPC::Fukuoka 2025 アプリケーションコード:ブラックボックス的利用 • モジュール 中身を知らなくても使える ◦ インターフェースだけわかれ よい ◦

    何をするかがわかれ よい ◦ どうやっているか 知らなくてよい • モジュール 全容を把握する必要 ない ◦ インターフェースが安定していれ よい ◦ 内部実装 知らなくてよい ◦ 後方互換性が保たれていれ よい • パブリックなモジュールもそ まま使えることが多い ◦ インターフェースが明確に定義されている ◦ 処理 抽象化により汎用的な要件として利用できる
  40. YAPC::Fukuoka 2025 利用 しかた 違い • モジュール 中身を理解して使う必要がある • モジュール

    全容が把握しやすい必要がある • パブリックなモジュールをそ まま使う 難しい インフラコード:ホワイトボックス的利用 アプリケーションコード:ブラックボックス的利用 • モジュール 中身を知らなくても使える • モジュール 全容を把握する必要 ない • パブリックなモジュールもそ まま使えることが多い
  41. YAPC::Fukuoka 2025 04 利用 しかた まとめ • 抽象化 しやすさ 違いがモジュール

    利用 しかたに影響する ◦ インフラコード:詳細 把握が必要 ◦ アプリケーションコード:詳細 把握 不要 • モジュール 利用 しかた ◦ インフラコード:ホワイトボックス的利用 ▪ モジュール 中身を理解して使う必要がある ▪ パブリックなモジュールをそ まま使う 難しい ◦ アプリケーションコード:ブラックボックス的利用 ▪ モジュール 中身を知らなくても使える ▪ パブリックなモジュールもそ まま使えることが多い • こ 違い モジュール設計に影響する
  42. YAPC::Fukuoka 2025 利用 しかた 違いがモジュール設計に影響 • 4章で見た利用 しかた 違い ◦

    インフラコード:ホワイトボックス的利用 ▪ モジュール 中身を理解して使う必要がある ◦ アプリケーションコード:ブラックボックス的利用 ▪ モジュール 中身を知らなくても使える • こ 違い モジュール設計 考え方に影響する ◦ ホワイトボックス的利用 → 内部構造 可視性を重視 ◦ ブラックボックス的利用 → 抽象性・階層化を重視 • インフラコードとアプリケーションコードで 、設計 優先順位が異なる
  43. YAPC::Fukuoka 2025 インフラコード:内部構造 可視性を重視 • モジュール 中身を理解する必要がある ◦ → 内部構造が見えるように設計する

    • 内部構造 可視性を高めるため 設計 ◦ 内部構造が見えやすい粒度で分割する ◦ 階層を深くしすぎない ◦ 階層 深さを統一する • 抽象化しすぎると逆効果 ◦ 何が作られるか見えなくなる ◦ 依存関係が隠蔽される ◦ 値 定義と使用 場所が離れ、実際 設定が把握しにくい ◦ 内部構造が見えなくなる
  44. YAPC::Fukuoka 2025 アプリケーションコード:抽象性・階層化を重視 • モジュール 中身を知る必要がない ◦ → 抽象化して詳細を隠す設計をする •

    抽象性を高めるため 設計 ◦ インターフェースを明確にする ◦ 実装 詳細を隠蔽する ◦ 階層化して複雑さを管理する • 抽象化が設計 基本 ◦ 処理 流れが理解できれ よい ◦ 実装 詳細 変更可能 ◦ モジュール 独立性が高まる
  45. YAPC::Fukuoka 2025 インフラコード:階層化 問題 • 2段構成でも問題が発生 ◦ 本来一緒に管理すべきリソースが分離される ◦ 内部構造が見えにくくなる

    • 3段構成以上で さらに深刻 ◦ 「まとめすぎ」と「細分化しすぎ」が同時に存在 ◦ 内部構造 把握と依存関係 追跡が困難 • 階層 深さが統一されていないとさらに問題 ◦ あるモジュール 2段、別 モジュール 3段、また別 4段 ◦ 統一性 なさが内部構造 把握を困難にする • インフラコードで 階層化 慎重に ◦ 階層を深くするほど内部構造 可視性が損なわれる ◦ 階層 深さを統一することも重要
  46. YAPC::Fukuoka 2025 アプリケーションコード:階層化 メリット • 階層化 複雑さを管理する有効な手段 ◦ 適切に抽象化すれ 、各層

    役割が明確になる • 階層化による整理 例(データベース操作) ◦ ORM → database/sql → ドライバ ◦ 各層が明確なインターフェースを提供し、実装 詳細を隠蔽 • 階層が深くても問題になりにくい ◦ 各層 インターフェースを理解すれ よい ◦ 実装 詳細 隠蔽されている • インフラコードと 対比 ◦ 階層化が設計 基本的な手法 ◦ 深い階層も適切に設計すれ 問題ない
  47. YAPC::Fukuoka 2025 設計 優先順位 違い • 内部構造が見えやすい粒度で分割する • 階層を深くしすぎない •

    階層 深さを統一する インフラコード:内部構造 可視性を重視 アプリケーションコード:抽象性・階層化を重視 • インターフェースを明確にする • 実装 詳細を隠蔽する • 階層化して複雑さを管理する
  48. YAPC::Fukuoka 2025 05 設計へ 影響 まとめ • 利用 しかた 違いが設計

    優先順位に影響する ◦ インフラコード:ホワイトボックス的利用 ◦ アプリケーションコード:ブラックボックス的利用 • 設計 優先順位が異なる ◦ インフラコード:内部構造 可視性を重視 ▪ 内部構造が見えやすい粒度で分割する ▪ 階層を深くしすぎない ▪ 階層 深さを統一する ◦ アプリケーションコード:抽象性・階層化を重視 ▪ インターフェースを明確にする ▪ 実装 詳細を隠蔽する ▪ 階層化して複雑さを管理する • こ 違いがインフラコード モジュール化を難しくしている
  49. YAPC::Fukuoka 2025 02-05章 まとめ • 記述 対象 違い ◦ インフラコード:状態を記述

    → 詳細が関心事 ◦ アプリケーションコード:処理を記述 → 処理が何をするかが関心事 • 抽象化 目的 違い ◦ インフラコード:構成 パターン化 ◦ アプリケーションコード:処理 カプセル化 • 利用 しかた 違い ◦ インフラコード:ホワイトボックス的利用 ◦ アプリケーションコード:ブラックボックス的利用 • 設計 優先順位 違い ◦ インフラコード:内部構造 可視性を重視 ◦ アプリケーションコード:抽象性・階層化を重視 • これら 違いが、インフラコード モジュール化を難しくしている
  50. YAPC::Fukuoka 2025 難しさとどう向き合うか • これまで見てきた難しさ ◦ インフラコード 詳細が関心事で抽象化しにくい ◦ ホワイトボックス的利用が必要で、内部構造

    可視性を重視する必 要がある ◦ ブラックボックス的利用を前提としたアプリケーションコード 感覚で モジュール化すると問題が起きる • こ 本質的な違いを理解した上で、向き合い方を考えてみます • 基本的に Terraform 話になります
  51. YAPC::Fukuoka 2025 向き合わない • 無理にモジュール化しない ◦ シンプルに保つ ◦ 必要になるまでモジュール化を避ける •

    YAGNI (You Aren't Gonna Need It) ◦ 本当に必要になってから考える • 事例: バイセルテクノロジーズ* ◦ 共通moduleを廃止してシンプルな構成に変更 ◦ チーム全員がメンテナンスできることを優先 * https://tech.buysell-technologies.com/entry/modify_terrafrom_architecture
  52. YAPC::Fukuoka 2025 ディレクトリ分割 • ディレクトリ分割も広義 モジュール化 • 機能的凝集を意識して分割する ◦ 右

    図 あくまでも一例 ◦ 巷 ベストプラクティスに囚われるな • なるべくお互いに依存しないような形でわける • 依存がある場合、変更 少ないも に依存する • Terraform ディレクトリ構成 変更 割と容易にできる で気軽にやる ◦ import/moved/removedブロックやtfmigrate*を活 用 ◦ 安全に変更するため CI/CDワークフローを組む * https://github.com/minamijoyo/tfmigrate
  53. YAPC::Fukuoka 2025 ファイル分割 • ファイル分割も広義 モジュール化 • これも機能的凝集を意識する ◦ 論理的凝集に

    しない ▪ 例: security_groups.tfにセキュリティグループを詰め込む 避 ける • main.tfというファイル名 避ける ◦ 機能を表す適切な名前にする ◦ ただしひとつしかtfファイルがない場合 main.tfでも問題ない ◦ そもそも状態を記述している で、処理 起点となるmainなエントリ ポイント 存在しない • Terraform ファイル構成を後からいくらでも変更できる で気軽にやる
  54. YAPC::Fukuoka 2025 モジュール機能 利用 • これも機能的凝集を意識する • 誤ったDRYに注意 ◦ 表面的な類似性だけで共通化しない

    • モジュール 目的や内容が予測しやすい名前や構成にする ◦ 例: ecsで なくecs_on_managed_instances • 組織や機能に適したデフォルト設定を内部で定義する ◦ 合意形成が重要 • 階層を深くしすぎない、階層 深さを統一する • レベル分けする もあり ◦ CDK L2, L3コンストラクト ようなイメージ
  55. YAPC::Fukuoka 2025 パブリックモジュール 原則として利用しない • 汎用的すぎる ◦ 論理的凝集になっていて機能的凝集になっていない ◦ 共有される知識(変数)が多い

    ▪ 大量 変数を公開し、内部モデルをそ まま共有(モデル結合) ▪ 浅いモジュール:複雑性をカプセル化できていない ▪ 境界を越えて共有される知識を削減できていない ▪ 利用者 認知負荷を増加 • なぜインフラコード これが起こる か ◦ 詳細が関心事な で、抽象化できる範囲が限定的 ◦ 汎用性を求めると、あらゆるケースに対応しようとする ▪ 機能を詰め込む(論理的凝集) ▪ 細分化しすぎる(制御結合) ▪ 内部モデルをそ まま大量 変数として公開(モデル結合、漏れ ある抽 象化)
  56. YAPC::Fukuoka 2025 06 難しさとどう向き合うか まとめ • 向き合わない ◦ 無理にモジュール化しない、YAGNI ◦

    シンプルに保つことを優先 • ディレクトリ分割・ファイル分割 ◦ 論理的凝集で なく機能的凝集を意識 • モジュール機能 利用 ◦ 論理的凝集で なく機能的凝集を意識 ◦ 組織や機能に適したデフォルト設定を内部で定義する ◦ 階層を深くしすぎない、階層 深さを統一する • パブリックモジュール 原則として利用しない ◦ 汎用的すぎて論理的凝集・制御結合になりやすく、内部モデルをそ まま大量 変数として露出している(モデル結合、漏れ ある抽象化) ◦ 組織内で管理されたモジュールを使うか、自作する
  57. YAPC::Fukuoka 2025 本発表 まとめ • インフラコードとアプリケーションコード 本質的に異なる ◦ インフラコード:状態を記述 →

    詳細が関心事 → 構成 パターン化 ◦ アプリケーションコード:処理を記述 → 処理が何をするかが関心事 → 処理 カプセル化 • こ 違いがモジュール化 難しさを生む ◦ インフラコード:内部構造 可視性が必要(ホワイトボックス的利用) ◦ アプリケーションコード:抽象化が可能(ブラックボックス的利用) • 難しさを理解した上で、適切に向き合う ◦ 無理にモジュール化しない(YAGNI) ◦ 機能的凝集を意識する ◦ 組織や機能に適したデフォルト設定を内部で定義する ◦ 階層を深くしすぎない、階層 深さを統一する ◦ パブリックモジュール 原則として使わず、組織内で管理する
  58. YAPC::Fukuoka 2025 CREDITS: This presentation template was created by Slidesgo,

    and includes icons, infographics & images by Freepik Thank you mizzy.org mizzy gosukenator