iT邦幫忙

2025 iThome 鐵人賽

DAY 3
1

在上一篇分享了 Terraform 如何運作,這篇來看看它的組成架構🤓

https://ithelp.ithome.com.tw/upload/images/20250903/20166287VEL2EJjmAh.png

Variables

提供動態參數,讓配置檔案變得更加靈活且可以重用。想像一下,如果你要在不同環境(開發、測試、正式)部署相同架構的內容,如果沒有 Variables 你就得寫三份幾乎相同的配置檔案!舉個例子比較一下差別~

沒有使用 Variables,你就需要寫幾乎相同的三份配置檔案:

# dev.tf - 開發環境
resource "google_compute_instance" "web_server" {
  name         = "dev-web-server"
  machine_type = "e2-micro"
  project      = "my-dev-project"
}

# test.tf - 測試環境  
resource "google_compute_instance" "web_server" {
  name         = "test-web-server"
  machine_type = "e2-small"
  project      = "my-test-project"
}

# prod.tf - 正式環境
resource "google_compute_instance" "web_server" {
  name         = "prod-web-server"
  machine_type = "e2-standard-2"
  project      = "my-prod-project"
}

使用 Variables:

# 定義變數
variable "project_id" {
  description = "GCP 專案 ID"
  type        = string
}

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

variable "environment" {
  description = "環境名稱"
  type        = string
}

# 一份配置適用所有環境
resource "google_compute_instance" "web_server" {
  name         = "${var.environment}-web-server"
  machine_type = var.machine_type
  project      = var.project_id
}

然後只需要用不同變數檔案來區分環境:

# 開發環境
terraform apply -var-file="dev.tfvars"

# 測試環境  
terraform apply -var-file="test.tfvars"

# 正式環境
terraform apply -var-file="prod.tfvars"

登愣!這就是 Variables 的優勢,它就像是一個「控制面板」,一份配置只要搭配不同變數值就能適應各種需求!


Data Sources

很多時候會需要在「已存在的資源」基礎上建立新的資源,比如說在現有的 VPC 中建立 VM,這時候 Data Sources 就是用來協助查詢現在有哪些雲端資源!

舉個簡單的例子:

# 查詢現有的 VPC 網路
data "google_compute_network" "existing_vpc" {
  name = "my-existing-vpc"
}

# 查詢可用區域
data "google_compute_zones" "available" {
  region = "asia-east1"
}

Data Sources 就像是「探測器」,幫助你取得外部資源的即時資訊,讓 Terraform 能夠整合既有的基礎設施!


Resources

用來定義你想在雲端建立的具體資源。可以藉由 Resources 來告訴 Terraform 「我要一台 VM」或「我要一個資料庫」。 它會接收 Variables 和 Data Sources 的資料,並且整合起來。

現在我們把前面的 Variables 和 Data Sources 結合起來,看看完整的 Resource 配置:

resource "google_compute_instance" "web_server" {
  name         = "${var.environment}-web-server"  # 使用變數
  machine_type = var.machine_type                 # 使用變數
  project      = var.project_id                   # 使用變數
  zone         = data.google_compute_zones.available.names[0] # 使用查詢結果
  
  boot_disk {
    initialize_params {
      image = "ubuntu-2204-lts"
    }
  }
  
  network_interface {
    network = data.google_compute_network.existing_vpc.self_link # 使用查詢到的 VPC
    access_config {}
  }

從這個例子可以看出,Resources 在整體流程中扮演著資料中心樞紐的角色:

  • 接收輸入:從 Variables 取得動態參數(如專案 ID、機器規格),從 Data Sources 取得現有資源資訊(如現有的 VPC 網路、可用區域)
  • 執行建立:根據這些資訊實際建立、修改或刪除雲端資源
  • 產生輸出:建立完成後提供資源屬性(如 IP 位址、資源 ID 等)給 Outputs 使用

簡單來說,其他元件都是為了讓 Resources 更靈活、更實用而存在的!


Outputs

用來取得並顯示資源建立後的重要資訊。在資源建立以後,你需要知道它的 IP 位址、資料庫連線字串等等資訊,這時候就能從 Outputs 中得到這些資訊。

舉個簡單的例子:

output "vm_external_ip" {
  description = "VM 的外部 IP 位址"
  value       = google_compute_instance.web_server.network_interface[0].access_config[0].nat_ip
}

output "vm_name" {
  description = "VM 的名稱"
  value       = google_compute_instance.web_server.name
}

執行 terraform apply 後會顯示:

Outputs:
vm_external_ip = "34.80.123.45"
vm_name = "production-web-server"

Outputs 就像是資訊的出口,讓你知道部署完成後的重要資訊,也可以將這些資訊傳遞給其他配置使用~


Modules

將多個相關的資源和配置打包成可重用的單元。當你的基礎設施變複雜時,所有配置寫在一個檔案裡會變得很亂,而且遇到相同的架構模式會重複寫很多遍。Modules 幫你解決「程式碼重用和組織化」的問題。
想像一下,如果你要為不同團隊建立相同架構的環境,沒有 Modules 你就得一直複製貼上程式碼。有了 Modules,你可以把經過驗證的配置封裝起來,需要時直接調用就好。舉個例子:

建立一個完整的 web-server 模組 (modules/web-app/main.tf):

# === 模組內部包含多個相關資源 ===

# 1. VM 實例
resource "google_compute_instance" "app_server" {
  name         = "${var.environment}-app-server"
  machine_type = var.machine_type
  zone         = var.zone
  
  boot_disk {
    initialize_params {
      image = "ubuntu-2204-lts"
    }
  }
  
  network_interface {
    network = google_compute_network.app_vpc.self_link
    access_config {}
  }
}

# 2. VPC 網路
resource "google_compute_network" "app_vpc" {
  name = "${var.environment}-vpc"
  auto_create_subnetworks = false
}

# 3. 子網路
resource "google_compute_subnetwork" "app_subnet" {
  name          = "${var.environment}-subnet"
  network       = google_compute_network.app_vpc.self_link
  ip_cidr_range = "10.0.1.0/24"
  region        = var.region
}

# 4. 防火牆規則
resource "google_compute_firewall" "allow_http" {
  name    = "${var.environment}-allow-http"
  network = google_compute_network.app_vpc.name

  allow {
    protocol = "tcp"
    ports    = ["80", "443"]
  }
  
  source_ranges = ["0.0.0.0/0"]
}

# 5. 資料庫
resource "google_sql_database_instance" "app_db" {
  name             = "${var.environment}-db"
  database_version = "POSTGRES_13"
  
  settings {
    tier = var.db_tier
  }
}

在主配置中使用這個模組:

# 一次調用就建立完整的 web 應用架構
module "production_web_app" {
  source       = "./modules/web-app"
  environment  = "prod"
  machine_type = "e2-standard-2"
  db_tier      = "db-custom-2-4096"
  region       = "asia-east1"
  zone         = "asia-east1-a"
}

Modules 就像是架構的「積木」,可以將經過驗證的配置重複使用,既保持程式碼的整潔性,也確保基礎設施的一致性!


從以上的範例可以看到,Terraform 的元件們其實像是一套分工明確的系統:

  • Variables / Data Sources → 提供靈活的輸入資料。
  • Resources → 實際建立或管理雲端資源。
  • Outputs → 將重要資訊輸出,方便後續使用。
  • Modules → 將整個架構封裝,實現重用與標準化。

經過這三天,我們已經掌握了 Terraform 的核心架構了!接下來就一起進入動手實戰練習吧🤩🚀


上一篇
Day 02 - Terraform 如何運作!
下一篇
Day 04 - Terraform CLI 實戰(本機練習)
系列文
30 天 Terraform 學習筆記:從零開始的 IaC 實戰4
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言