terraformの公式ページを読んでもちゃんと理解できなかったので、ちょっとテスト的に動きを確認してみます!
Contents
第1構成「ただのdevでの実行。devにあるコードをそのままmodulesに移動させただけ。」
以下のような構成を考えました。

devは開発環境を想定
prdは本番環境を想定
そしてmodulesはdevとprdで共通の処理というかリソース。開発、本番共に作りたいcompute engineのインスタンスを作成する処理を記載(resource定義)
devのディレクトリにてterraform initを実行します。これによりdevディレクトリの情報でterraformは処理を行います。
なのでprdの影響を受けません。
そして、terraformにmodule機能はここにありますと定義するために、moduleブロックでsourceを定義します。
sourceに指定するパスは、コマンド実行したところを基準にしてパスを指定します。
今回devで実行するので、一度上にディレクトリを戻り(../)、そして/modules/compute_engine/がモジュールになるので、sourceには"../modules/compute_engine/"と指定します。
第2構成「moduleを変数化して、devディレクトリから変数を渡して処理をする」
少し本格的になりました。
これがわかれば、開発環境用のdevや本番環境用のprdにはそれぞれの変数(インスタンス名やGCSバケット名や、プロジェクト分けるならそれぞれプロジェクトIDなど)を入れておき、共通のresourceコードとしてmodulesで共通のコードを分ける。
上ではそのままdevで実行したが、modulesに下手に変数を直書きしてました。
やっぱ開発と本番で別々の変数を渡して実行したいというのがあります。
なのでここでちょっと検証です。

上のプログラムのdevのmain.tfを変更させて、以下のようにしてみました。
moduleのところに変数を入れてみます。
▼ terraform_test2/dev/main.tf
/** 開発環境の定義 **/
module "instance_compute_engine" {
source = "../modules/compute_engine/"
aaa_name = local.dev.instance_name
aaa_zone = local.dev.instance_zone
aaa_machine_type = local.dev.instance_machine_type
}
この状態で、terraform initしてterraform planを実行しました。
そうすると以下のようなエラーになりました。
argumentつまり引数がないとのことで、これはまさにmoduleは関数であるということを言ってますね。
moduleブロックにて、modulesディレクトリのmain.tfの中にあるresourceに渡すための変数を入れているが、resource側にて引数の定義をしていないため、エラーになっています。
なので、resourceにて引数の定義をします。
▼ terraform_test2/modules/compute_engine/
/** 変数の定義(ここでdevのmain.tfでのmoduleに指定した引数の値を受け取る **/
variable "aaa_name" {}
variable "aaa_zone" {}
variable "aaa_machine_type" {}
/** resourceの定義 **/
resource "google_compute_instance" "vm_instance" {
/** 上で受け取った変数値をここで使用する **/
name = var.aaa_name
zone = var.aaa_zone
machine_type = var.aaa_machine_type
boot_disk {
initialize_params {
image = "debian-cloud/debian-11"
}
}
network_interface {
# A default network is created for all GCP projects
network = "default"
access_config {
}
}
}
modulesのcompute_engineにはmain.tfのみで、そこで変数を宣言していますが、
variables.tfを作ってそこに変数を宣言してみても良いと思います!

実際のプログラムは以下のgithubにアップしてあります。
ぜひ初心者の方はローカルで実行してみてください!
第3構成「開発環境と本番環境それぞれ変数以外は同じプログラムで片方で実行した時、影響ないか」
開発環境と本番環境でGCPプロジェクトを分けるべきですが、prdにてコードを置いたときに、devのプログラムは処理されないかを確認してみます。
dev配下にあるプログラムをそのままprdにコピーし、以下2ファイルについて本番環境用に変数を変えてみます。
▼ /prd/variables.tf
引数の部分でlocal.prdにする。
localsにprdを入れて、そこに値を指定してます。prdのinstance_nameの値を変更してます。
/** 変数定義 **/
locals{
dev = {
instance_name = "terraform-instance-dev"
instance_zone = "us-central1-a"
instance_machine_type = "e2-micro"
}
prd = {
instance_name = "terraform-instance-prd"
instance_zone = "us-central1-a"
instance_machine_type = "e2-micro"
}
}
▼ /prd/main.tf
引数の部分でlocal.prdにしてます。
上で指定したlocalsのprdの値を以下のように引数に指定しています。
/** 開発環境の定義 **/
module "instance_compute_engine" {
source = "../modules/compute_engine/"
/** 引数的な感じ **/
aaa_name = local.prd.instance_name
aaa_zone = local.prd.instance_zone
aaa_machine_type = local.prd.instance_machine_type
}
これでprdディレクトリへ移動して、terraform init → terraform plan → terraform applyを実行すると、以下のように問題なく
terraform_instance_prdという名前でインスタンスが生成されました。
prdに移動してそこでterraformコマンドを実行しても、devに指定しているmain.tfなどの処理はされないということがわかりました。
全体のプログラムは以下を参照してください。
terraform_test3のプログラム
https://capsulecloud.io/terraform-variable
outputとは
https://qiita.com/kyntk/items/2cdd38c2438ac257ac4e



