Input & Output Variables – Bài 3

Khi làm việc với Terraform, việc tách các file cấu hình triển khai sẽ giúp dự án dễ bảo trì, mở rộng và áp dụng cho nhiều môi trường (Dev, Test, Production). Dưới đây là các cách quản lý biến trong Terraform: Variables File, Override Variables, và Output Variables.

Xem thêm:

Terraform và Infrastructure as Code (IAC) – Bài 1

Terraform init, plan và apply – Bài 2

1. Biến trong Terraform dùng để làm gì?

Khi làm việc với Terraform, mọi thứ đều xoay quanh configuration file (file cấu hình). Nếu chúng ta viết file cấu hình cố định (static), nó sẽ chỉ dùng được cho một dự án cụ thể. Điều này gây khó khăn khi triển khai trên nhiều môi trường (dev, staging, production).

Để giải quyết, Terraform cung cấp Variables (biến). Việc sử dụng biến giúp file cấu hình trở nên linh hoạt (flexible) và dùng lại được (reusable) ở nhiều môi trường mà không cần sửa trực tiếp file cấu hình.

Giải pháp: Tách các giá trị cấu hình vào một file riêng biệt, thường là variables.tf.

2. Cách định nghĩa biến trong Terraform

Terraform hỗ trợ 2 cách:

Cách 1: Định nghĩa đơn giản

variable "environment" {
  default = "dev"
}

Cách 2: Định nghĩa chi tiết (khuyến khích)

variable "location" {
  type        = string
  default     = "ap-southeast-1"
  description = "AWS region để deploy tài nguyên"
}

Trong block variable, bạn có thể khai báo:

  • type: kiểu dữ liệu (string, number, bool, list, map, object, tuple).
  • default: giá trị mặc định (nếu không truyền thì Terraform dùng giá trị này).
  • description: mô tả để dễ hiểu khi nhiều người cùng làm việc.

Thông thường, các biến sẽ được gom trong file variables.tf.

terraform-project/
├── main.tf
├── variables.tf

variables.tf:

variable "resource_group_name" {
  type        = string
  default     = "example-resources"
  description = "Tên của Resource Group"
}

variable "resource_group_location" {
  type        = string
  default     = "West Europe"
  description = "Vị trí của Resource Group"
}

variable "app_service_plan_name" {
  type        = string
  default     = "example-app-service-plan"
  description = "Tên của App Service Plan"
}

variable "app_service_name" {
  type        = string
  default     = "example-app-service"
  description = "Tên của App Service"
}

main.tf:

resource "azurerm_resource_group" "example" {
  name     = var.resource_group_name
  location = var.resource_group_location
}

resource "azurerm_app_service_plan" "example" {
  name                = var.app_service_plan_name
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  kind                = "App"

  sku {
    tier = "Standard"
    size = "S1"
  }
}

resource "azurerm_app_service" "example" {
  name                = var.app_service_name
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  app_service_plan_id = azurerm_app_service_plan.example.id
}

3. Validation (Xác thực giá trị biến)

Từ Terraform >= 0.13, bạn có thể thêm validation để giới hạn giá trị hợp lệ.

Ví dụ:

variable "location" {
  type        = string
  description = "Vùng AWS để deploy"
  
  validation {
    condition     = contains(["ap-southeast-1", "us-east-1"], lower(var.location))
    error_message = "Region không hợp lệ. Hãy chọn ap-southeast-1 hoặc us-east-1."
  }
}

Khi người dùng nhập sai giá trị, Terraform sẽ báo lỗi ngay.

4. Các kiểu dữ liệu trong Terraform Variables

Terraform chia thành Primitive TypesComplex Types.

4.1. Primitive Types

  • string → “Hello”
  • number → 10, 20.5
  • bool → true, false

4.2. Complex Types

Collection Types

  • list[ "dev", "staging", "prod" ]
  • map{ region = "ap-southeast-1", env = "prod" }
  • set["a", "b", "c"] (giá trị duy nhất, không trùng lặp)

Structural Types

  • object: tập hợp nhiều giá trị khác loại
    variable "user" {
      type = object({
        name = string
        age  = number
      })
    }
    
  • tuple: tập hợp giá trị có nhiều loại, theo thứ tự
    variable "example" {
      type = tuple([string, number, bool])
    }
    

5. Truyền giá trị cho biến

Có nhiều cách để cung cấp giá trị cho biến:

  1. File .tfvars
    environment = "prod"
    location    = "us-east-1"
    

    Chạy:

    terraform apply -var-file="prod.tfvars"
    
  2. Dòng lệnh
    terraform apply -var="environment=prod"
    
  3. Biến môi trường
    export TF_VAR_environment=prod
    terraform apply

6. Sử dụng Output Variables

Output variables giúp trích xuất và hiển thị thông tin từ các resource sau khi thực thi. Output có thể được sử dụng trong CI/CD pipeline, chia sẻ giữa các module, hoặc đơn giản là để hiển thị thông tin quan trọng sau khi deploy.

Ví dụ trích xuất các thông tin:

  • Địa chỉ IP của Virtual Machine hoặc Web App.
  • ID hoặc tên của một resource.
  • Hostname hoặc URL của một dịch vụ.
  • Truyền dữ liệu giữa các module Terraform.

Cấu trúc thư mục:

terraform-demo/
├── main.tf
├── variables.tf
└── outputs.tf

main.tf:

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "example" {
  name     = var.resource_group_name
  location = var.resource_group_location
}

variables.tf:

variable "resource_group_name" {
  type        = string
  default     = "demo-resource-group"
  description = "Tên của Resource Group"
}

variable "resource_group_location" {
  type        = string
  default     = "East US"
  description = "Vị trí của Resource Group"
}

outputs.tf:

output "resource_group_name" {
  description = "Tên Resource Group đã tạo"
  value       = azurerm_resource_group.example.name
}

output "resource_group_location" {
  description = "Vị trí của Resource Group"
  value       = azurerm_resource_group.example.location
}

Tách biệt phần khai báo và gán giá trị biến trong Terraform là một thực hành quan trọng giúp dự án dễ mở rộng, bảo trì và triển khai cho nhiều môi trường. Bằng cách sử dụng hợp lý variables.tf, .tfvars và outputs.tf, bạn sẽ có một kiến trúc hạ tầng rõ ràng và chuyên nghiệp hơn.

Nguyễn Tiến Trường

Mình viết về những điều nhỏ nhặt trong cuộc sống, Viết về câu chuyện những ngày không có em