iT邦幫忙

2025 iThome 鐵人賽

DAY 14
0

過去幾天,我們已經學過 Terraform 的基本元件:resourcevariableoutputdata source

但這些就像是散落一地的零件,雖然能組裝出機器,但每次都要自己拼,會很麻煩。

今天,我們要練習把這些零件「組裝」起來,做出我們的 第一個 Module
就像是寫程式時不會一直複製貼上,而是把功能包成 function,Terraform 的 module 也有同樣的精神!

🐈🐈🐈

為什麼要用 Module?

先舉個例子。假設公司要在開發、測試、正式三個環境,各建立 3 台 VM。

如果不用 module,我們就得把一大段 VM 的設定,複製貼上 9 次。不但程式碼很長,未來要改配置還得一個一個找,非常容易出錯。這就是為什麼 module 會登場。它讓我們把 VM 的邏輯抽出來,放到一個獨立的目錄,之後只要呼叫這個 module,再帶入不同的參數,就能快速建立多台 VM。

Root Module 與 Sub Module

首先,我們先釐清一個觀念:

Root Module(根模組)

  • 定義: 任何你執行 terraform initterraform apply 的工作目錄就是 Root Module
  • 特徵: 包含 .tf 設定檔案(可能叫 main.tfvariables.tf,也可能叫別的名字)
  • 職責: 作為整個基礎設施的入口點和協調中心

Sub Module(子模組)

  • 定義: 任何被其他模組透過 module 區塊呼叫的模組
  • 來源: 可以是本地目錄(如 ./modules/vm)、Git 倉庫、或 Terraform Registry
  • 職責: 專門負責建立特定類型的資源,提供可重複使用的功能

做個簡單的比喻:

  • Root Module = 建案總監(決定要蓋什麼、在哪蓋、什麼規格)
  • Sub Module = 專業包商(水電工、泥水工,各有專精,按照總監要求施工)

總監不需要知道水管怎麼接,只要告訴水電工「我要在這裡裝廁所」;水電工也不用管整體設計,專心把廁所裝好就行了。

建立第一個 VM Module

大概了解為什麼需要 Module 以及 Root Module 與 Sub Module 的差別後,我們就要實際嘗試建立一個 VM 的 module。

第一步:建立目錄結構

我們先新增一個 modules/vm 目錄,裡面放三個檔案:

modules/vm/
├── main.tf
├── variables.tf
└── outputs.tf

這就是一個最小的 module 架構。

第二步:在 module 裡定義 VM

modules/vm/main.tf 裡面,我們把 VM 的資源定義好:

resource "google_compute_instance" "this" {
  name         = var.name
  machine_type = var.machine_type
  zone         = var.zone

  boot_disk {
    initialize_params {
      image = var.image
      size  = var.disk_size
    }
  }

  network_interface {
    network = var.network
    access_config {}
  }

  tags = var.tags
}

大家可以看到這裡沒有寫死 VM 名稱、機型、zone,而是透過 var.xxx 從變數帶進來。

第三步:定義變數

modules/vm/variables.tf 裡,把需要的變數列出來:

variable "name" {
  description = "VM 名稱"
  type        = string
}

variable "machine_type" {
  description = "機器規格"
  type        = string
  default     = "e2-micro"
}

variable "zone" {
  description = "部署區域"
  type        = string
  default     = "asia-east1-b"
}

variable "image" {
  description = "作業系統映像檔"
  type        = string
  default     = "debian-cloud/debian-11"
}

variable "disk_size" {
  description = "開機磁碟大小 (GB)"
  type        = number
  default     = 10
}

variable "network" {
  description = "VPC 網路名稱"
  type        = string
  default     = "default"
}

variable "tags" {
  description = "網路標籤"
  type        = list(string)
  default     = []
}

這樣我們就能在呼叫 module 的時候,靈活決定 VM 的細節。

第四步:輸出 VM 資訊

modules/vm/outputs.tf 裡,定義一些常用的輸出資訊,例如 VM 名稱、內外部 IP:

output "instance_name" {
  value = google_compute_instance.this.name
}

output "internal_ip" {
  value = google_compute_instance.this.network_interface[0].network_ip
}

output "external_ip" {
  value = google_compute_instance.this.network_interface[0].access_config[0].nat_ip
}

第五步:在 Root Module 呼叫

最後回到專案根目錄main.tf,我們就能用簡單的方式呼叫這個 module:

module "dev_vm1" {
  source = "./modules/vm"
  name   = "dev-vm-1"
  tags   = ["development", "web"]
}

module "prod_vm1" {
  source       = "./modules/vm"
  name         = "prod-vm-1"
  machine_type = "e2-standard-2"
  zone         = "asia-east1-c"
  disk_size    = 50
  tags         = ["production", "web"]
}

output "dev_vm1_info" {
  value = {
    name        = module.dev_vm1.instance_name
    external_ip = module.dev_vm1.external_ip
  }
}

output "prod_vm1_info" {
  value = {
    name        = module.prod_vm1.instance_name
    external_ip = module.prod_vm1.external_ip
  }
}

這樣只要呼叫一次,就能建立一台 VM;改變參數,就能快速建立不同規格的 VM。

執行看看

terraform init
terraform plan
terraform apply

執行完成後,可以用 terraform output 查看剛剛輸出的 VM 名稱與 IP~

https://ithelp.ithome.com.tw/upload/images/20250914/20166287SkpS631kIL.png

登愣!用了 module 之後就不用一直複製貼上重複的設定,還能把資源打包成可重複利用的積木,維護起來更清楚又有效率!

總結一下:

今天我們踏出了*模組化基礎建設的第一步~

  • 嘗試把 VM 建立的程式碼抽出來,封裝成 modules/vm
  • 練習在 root module 只要呼叫一次,就能快速產生不同環境的 VM
  • 也可以透過輸出 (outputs),方便地取得 VM 的名稱與 IP,也不用自己到 Console 一個個找

更重要的是!

Module 讓我們的 Terraform 程式碼,從「一次性寫死」升級成「可重複使用的積木」。

未來不管是要建更多 VM,還是要調整參數,只要改 Module 就能影響所有呼叫它的地方,既減少錯誤,又讓架構設計更清晰。

這就是基礎建設自動化真正的好處:一次設計,多次使用,輕鬆擴展。

🐈🐈🐈

明天要了解模組設計的原則與參數管理技巧,讓我們寫的 module 不只是能用,而是好用、耐用且可重複使用!


上一篇
Day 13 - Terraform Resource 關係管理:depends_on、implicit dependencies
系列文
30 天 Terraform 學習筆記:從零開始的 IaC 實戰14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言