5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

main.tf をやめよう —— C・Python・Terraform の「言語仕様」から考えるファイル名

5
Last updated at Posted at 2026-08-14

TL;DR

  • C の main、Python の __main__ は言語仕様・処理系が名前で探しに来るから意味がある。改名できないし、プログラム内に1つしかない。
  • Terraform はディレクトリ内の全 .tf をまとめて読んで、ひとつのドキュメントとして評価するだけなので、main.tfは技術的には意味がない。
  • ファイル名は Terraform にとって意味がないこそ100%人間のための索引として使うべきで、network.tf / lb.tf のようにリソースを表現する名前にした方がいい。
  • ただし modules/vpc/main.tf のようにディレクトリ名が意味を担っている小さなモジュールでは許容できる。

1. そもそも言語における main とは何だったのか

main.tf を批判する前に、いったん他の言語で main がなぜ main なのかを確認しておきたい。

C言語

C では、ホスト環境においてプログラム開始時に呼ばれる関数の名前は main であると規格が定めている(ISO C の "Program startup")。

実行の流れは、ざっくりこうなっている。

kernel → ELFの entry point (_start) → __libc_start_main → main()

カーネルがバイナリの entry point にジャンプし、そこに配置された C ランタイムの初期化コードが、argc / argv / 環境変数を整えてから main を呼ぶ。

だから通常の C プログラムで mainstart に改名すると、リンク時に「参照先が見つからない」と怒られる。

Python

Python にはエントリポイント関数はないが、代わりに __main__ という名前がある。

if __name__ == "__main__":
    main()

このイディオムが成立するのは、インタープリタが「トップレベルで実行中のモジュールの __name__"__main__" にする」と決めているから。

さらに python -m mypackage を実行すると、処理系は mypackage/__main__.py を探して実行する。ここではファイル名そのものが仕様の一部になっている。名前を entry.py に変えたら動かない。

Go / Java も同じ構図

  • Go: 実行可能プログラムは package mainfunc main() を持たなければならない、と言語仕様が定めている。
  • Java: JVM が public static void main(String[] args) というシグネチャを探しに来る。

共通点

どの言語でも、main には次の3つの性質がある。

  1. 処理系がその名前を探しに来る(規約ではなく仕様)
  2. 改名できない
  3. プログラム内に1つしかない(唯一だから「ここから始まる」という情報になる)

main という名前は「ここが起点だ」という情報を運んでいる。情報を運んでいるから、名前として価値がある。

2. Terraform には main に相当する概念がない

では Terraform はどうか。

Terraform evaluates all of the configuration files in a module, effectively treating the entire module as a single document. Separating various blocks into different files is purely for the convenience of readers and maintainers, and has no effect on the module's behavior.

— Files and configuration structure

ポイントは3つある。順番に見ていく。

(1) 全ファイルがマージされる。
terraform plan / apply を実行したディレクトリの .tf を全部読み込んで、実質的に1つの設定として扱う。

(2) 評価順にファイルは関係しない。
HCL は宣言的な言語で、実行順序はファイルの並びではなくリソース間の依存グラフから決まる。「先に読まれるファイル」という概念に意味がない以上、「最初に読むべきファイル」を示す名前にも意味がない。

(3) main.tf という名前を Terraform 本体は一切参照していない。
main.tf が存在しなくても動く。全部 network.tf でも動く。aaa.tf でも 20260814.tf でも動く。

ちなみに、Terraform にも「名前が意味を持つファイル」はある

「Terraform ではファイル名に一切意味がない」というのは正確ではなく、名前が意味を持つファイルは存在する。

  • override.tf / _override.tf —— 通常のファイルを全部読み込んだ後に読まれ、連結ではなくマージ(上書き)される。読み込みタイミングも意味論も他と違う。
  • .tf.json —— 拡張子で HCL か JSON かを切り替える。
  • terraform.tfvars / .auto.tfvars —— 自動で読み込まれる変数ファイル。

つまり Terraform は「ファイル名に意味を持たせたいときは、ちゃんと仕様で定義する」という設計をしている。main.tf が仕様に入っていないということは、Terraformの設計者が「これは意味を持たせるべき名前ではない」と判断したということ。

3. main.tf はあなたに何を伝えているのか

Terraform にとってファイル名が無意味だということは、裏を返せば、ファイル名は100%人間のためだけに存在するということだ。

人間のためだけの命名機会を、main という中身ゼロの単語に使うのはもったいない。

main.tf というファイル名から、中身が想像できるだろうか?

せいぜい分かるのは「このリポジトリが Terraform を使っている」ことくらいかな?

一方こうだったらどうか。

.
├── terraform.tf     # required_version, required_providers
├── providers.tf     # provider ブロック
├── variables.tf
├── locals.tf
├── network.tf       # VPC, subnet, route table, NAT GW
├── lb.tf            # ALB, target group, listener
├── ecs.tf           # cluster, service, task definition
├── rds.tf
├── iam.tf
├── monitoring.tf
└── outputs.tf

ALB のヘルスチェック設定を直したい人は、迷わず lb.tf を開く。目次があるのと同じだ。

main.tf が表すものは何か?

「これはどこに書くべきか」を判断する基準がファイルという実態に存在しないため、結果として 数百行の main.tf が生まれる。

network.tf にはこれが起きにくい。aws_db_instancenetwork.tf に書こうとすると、書いている本人が「いや、これは違うな」と気づけるからだ。

4. 公式スタイルガイドはどう言っているか(正直に)

実は、HashiCorp の公式スタイルガイドは main.tf を推奨している。 「全ての resource ブロックと data source ブロックを含む main.tf」という記述がある。

ただし、同じページのすぐ続きにこう書いてある(Style Guide - File names)。

As your codebase grows, limiting it to just these files can become difficult to maintain. If your code becomes hard to navigate due to its size, we recommend that you organize resources and data sources in separate files by logical groups.

そして例として挙げられているのが、まさに network.tf / storage.tf / compute.tf だ。さらに判断基準が明記されている。

No matter how you decide to split your code, it should be immediately clear where a maintainer can find a specific resource or data source definition.

この一文がすべてを決めている。つまり、「どこに何があるか即座に分かる」が公式の基準なのだ。

公式ガイドを正しく読むと、main.tf は小さなモジュールの出発点として提示されているのであって、終着点として推奨されているわけではない。かなり雑に言えば、「まず main.tf に書け、育ったら分けろ」と言っている。

5. main.tf が許容できるケース

自分も main をすべて駆逐しろと思っているわけじゃない。「意味を持っているか」が問題なので、main.tf が許容できるケースも挙げておく。

ディレクトリ名が意味を担っている、単一目的の小さいモジュール

modules/
├── vpc/
│   ├── main.tf       # ← これは許容できる
│   ├── variables.tf
│   └── outputs.tf
└── rds/
    ├── main.tf
    ├── variables.tf
    └── outputs.tf

modules/vpc/main.tf を開く人は、開く前から「VPC のコードだ」と知っている。意味を運んでいるのはファイル名ではなくパスだ。 この構造では main.tf は「このモジュールの本体」というマーカーとして機能する。variables.tf / outputs.tf が入出力インターフェース、main.tf が実装、という main / sub の対比は成立している。

言い換えると、main を「唯一の起点」ではなく「主 / 従」の対比として使う分には筋が通る。

一方、これは避けたい

.
├── main.tf          # ← 800行!!! VPC も ALB も RDS も IAM も全部入り!!
├── variables.tf
└── outputs.tf

コードがでかくなるなら分割しよう!!!

判断基準

そのファイル名(またはパス)を見て、中に何があるか分かるか。 分かるなら main.tf でもいい。分からないなら名前を変えるべきだ。結局、公式ガイドが言っているのもこれと同じことだと思う。

まとめ

main という名前は、C でも Python でも Go でも Java でも、処理系がその名前を探しに来るから意味を持っている。名前が契約になっていて、改名できず、プログラム内に1つしかない。だから「ここが起点だ」という情報を運べる。

Terraform の main.tf にはそれがない。Terraform はディレクトリ内の全 .tf を等価にマージするだけで、main.tf という名前をどこからも参照していない。名前の見た目だけを他言語から借りて、意味は借りられていない。

そしてファイル名が Terraform にとって無意味だからこそ、それは人間のためだけの索引になる。唯一の命名機会を「main」という何も語らない単語に使う理由はない。

  • ファイル名から中身が分かるか?
  • PR の差分を見た瞬間に影響範囲が分かるか?
  • 障害対応中に開くべきファイルが即決できるか?

少なくともルートモジュールの巨大な main.tf は、これを1つも満たさない。ただ、ディレクトリ名が意味を担っている小さなモジュールなら main.tf でもいい。

意味のない main.tf はやめよう。

参考

  • Files and configuration structure - Terraform —— 全 .tf を単一ドキュメントとして評価する仕様
  • Style Guide - Terraform —— ファイル名の推奨と、論理グループへの分割指針
  • Override Files - Terraform —— 仕様上、名前が意味を持つ数少ないファイル
  • ISO/IEC 9899 §5.1.2.2.1 Program startup —— C における main の定義
  • __main__ — Top-level code environment - Python docs
  • The Go Programming Language Specification - Program execution
5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?