Trong các dự án hạ tầng doanh nghiệp quy mô lớn, việc quản lý các tham số đầu vào (Variables), tính toán các giá trị trung gian (Locals) và xuất dữ liệu liên kết giữa các module (Outputs) đòi hỏi một tiêu chuẩn kiến trúc nghiêm ngặt. Nếu không có cơ chế kiểm tra tính hợp lệ dữ liệu ngay từ đầu (Input Validation) và che giấu dữ liệu nhạy cảm (Sensitive Masking), hệ thống của bạn sẽ đối mặt với rủi ro rò rỉ mật khẩu cơ sở dữ liệu trên log CI/CD hoặc lỗi triển khai hạ tầng do nhập sai định dạng mạng CIDR.
Bài viết này sẽ hướng dẫn bạn toàn bộ quy chuẩn thiết kế Variables, Locals và Outputs chuyên nghiệp nhất theo khuyến nghị của HashiCorp.
1. Thứ Tự Ưu Tiên Giá Trị Biến (Variable Precedence)
Khi cùng một biến được khai báo ở nhiều vị trí khác nhau, Terraform sẽ giải quyết xung đột dựa trên thứ tự ưu tiên nghiêm ngặt từ thấp đến cao:
Bảng Phân Tầng Thứ Tự Nạp Biến:
- Giá trị
default: Khai báo bên trong blockvariable(mặc định thấp nhất). - Biến môi trường hệ thống: Các biến có tiền tố
TF_VAR_ten_bien(ví dụ:export TF_VAR_environment="staging"). - Tệp
terraform.tfvars: Tự động được nạp nếu tồn tại trong thư mục thực thi. - Tệp
*.auto.tfvarshoặc*.auto.tfvars.json: Tự động nạp theo thứ tự từ điển alphabet. - Tham số dòng lệnh CLI
-varvà-var-file: Có quyền ghi đè cao nhất (ví dụ:terraform plan -var-file=env/prod.tfvars).
2. Thiết Lập Custom Validation Rules Cho Input Variables
Bắt đầu từ Terraform 0.13+, bạn có thể gắn một hoặc nhiều khối validation vào biến để bắt lỗi sai dữ liệu ngay lập tức tại bước terraform plan trước khi gửi bất kỳ API call nào lên Cloud:
variable "environment" {
type = string
description = "Moi truong trien khai (chi chap nhan: dev, staging, prod)"
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Gia tri moi truong khong hop le! Chi chap nhan 'dev', 'staging' hoac 'prod'."
}
}
variable "vpc_cidr" {
type = string
description = "Dia chi IP CIDR cua VPC (yeu cau format IPv4 chuan)"
validation {
condition = can(cidrnetmask(var.vpc_cidr)) && (tonumber(split("/", var.vpc_cidr)[1]) <= 24)
error_message = "VPC CIDR phai la dia chi IPv4 hop le va co subnet mask toi thieu /24."
}
}
3. Tối Ưu Hóa Local Values (DRY Principle)
locals hoạt động như các hằng số hoặc biến trung gian được tính toán nội bộ. Hãy sử dụng locals để chuẩn hóa định danh và gán Tagging đồng bộ cho toàn bộ tài nguyên:
locals {
# Chuan hoa prefix ten tai nguyen
name_prefix = "showtech-${var.project_name}-${var.environment}"
# Base Tags dong bo toan bo he thong
common_tags = {
Project = var.project_name
Environment = var.environment
ManagedBy = "Terraform"
CostCenter = "Core-Engineering"
UpdatedAt = formatdate("YYYY-MM-DD", timestamp())
}
}
resource "aws_s3_bucket" "app_bucket" {
bucket = "${local.name_prefix}-data-lake"
tags = local.common_tags
}
4. Bảo Vệ Dữ Liệu Nhạy Cảm Với sensitive = true
Rủi ro rò rỉ thông tin (Secret Leakage): Nếu bạn xuất Password Database, Private Key TLS hoặc API Token qua output mà không gắn cờ sensitive = true, toàn bộ giá trị này sẽ bị in ra dưới dạng plain text trên màn hình console và log của các hệ thống CI/CD (GitHub Actions, Jenkins).
# outputs.tf - Che giau du lieu nhay cam
output "rds_endpoint" {
value = aws_db_instance.postgres.endpoint
description = "Dia chi ket noi Database Postgres (Publicly Viewable)"
}
output "db_master_password" {
value = aws_db_instance.postgres.password
description = "Mat khau Master cua Database (Strictly Protected)"
sensitive = true # Bat buoc co de ngan chan in ra console
}
Khi chạy terraform apply, Terraform sẽ bảo vệ thông tin:
Outputs:
db_master_password = <sensitive>
rds_endpoint = "showtech-prod-db.c9ak11x.ap-southeast-1.rds.amazonaws.com:5432"
5. Bảng So Sánh Kỹ Thuật: Khi Nào Dùng Variables vs Locals vs Outputs
| Tiêu Chí | Input Variables (var) |
Local Values (local) |
Output Values (output) |
|---|---|---|---|
| Mục Đích | Nhận tham số cấu hình từ bên ngoài | Tính toán logic và chuẩn hóa nội bộ | Trả kết quả ra màn hình hoặc module cha |
| Phạm Vi (Scope) | Toàn module (Nhận từ CLI / tfvars) | Cục bộ bên trong module đó | Ra ngoài module hoặc dùng cho Remote State |
| Khả Năng Thay Đổi | Linh hoạt theo từng môi trường | Cố định theo công thức tính toán | Phụ thuộc vào thuộc tính tài nguyên tạo ra |
| Hỗ Trợ Validation | Có (validation block) |
Không cần (Tự tính trong code) | Có hỗ trợ precondition (TF 1.2+) |
6. Production War Story: Ngăn Chặn Thảm Họa Nhầm Lẫn Môi Trường (Prod vs Dev)
Bài toán thực tế: Một kỹ sư sơ ý chạy lệnh terraform apply tại thư mục Production nhưng lại trỏ nhầm tệp cấu hình dev.tfvars của môi trường thử nghiệm, suýt nữa làm hạ cấp quy mô cụm cơ sở dữ liệu từ 64 CPU xuống còn 2 CPU.
Giải Pháp Phòng Thủ Nhiều Lớp Bằng Check Rule:
Thêm khối validation kiểm tra chéo giữa tên Workspace/Branch với biến môi trường:
variable "environment" {
type = string
validation {
condition = var.environment <mark class="tech-highlight"> "prod" ? terraform.workspace </mark> "production" : true
error_message = "LỖI BẢO MẬT: Không thể áp dụng cấu hình Production khi đang ở Workspace '${terraform.workspace}'!"
}
}
Nhờ cơ chế này, lệnh apply bị chặn đứng ngay lập tức tại máy trạm của kỹ sư mà không thể gây tổn hại cho hạ tầng thật.
7. Câu Hỏi Phỏng Vấn Kỹ Sư Cao Cấp (Senior Terraform Q&A)
Q1: Cờ sensitive = true trên variable và output có giúp mã hóa dữ liệu nhạy cảm bên trong State File (terraform.tfstate) hay không?
Trả lời:
KHÔNG. Cờ sensitive = true chỉ có tác dụng ngăn chặn Terraform in giá trị ra màn hình CLI, console logs và UI. Trong State File (.tfstate), toàn bộ giá trị vẫn được lưu trữ dưới dạng Plain Text JSON. Do đó, ở cấp độ Production, bắt buộc phải mã hóa State File bằng Server-Side Encryption (AWS KMS / S3 Default Encryption) và phân quyền IAM chặt chẽ.
Q2: Nếu trong cùng một thư mục có cả terraform.tfvars, production.auto.tfvars và biến môi trường TF_VAR_region, giá trị nào sẽ thắng?
Trả lời:
Theo thứ tự ưu tiên của Terraform:
production.auto.tfvars sẽ chiến thắng terraform.tfvars và TF_VAR_region. Thứ tự là: TF_VAR_ (thấp) $\rightarrow$ terraform.tfvars $\rightarrow$ *.auto.tfvars (cao nhất trong các tệp tự động nạp).
8. Tổng Kết Giai Đoạn 1
Với 5 bài viết đầu tiên, chúng ta đã xây dựng nền tảng vững chắc nhất về Tư duy Declarative, Vòng đời thực thi & DAG, Cú pháp HCL hiện đại và Quy chuẩn quản trị Variables/Locals/Outputs.
Trong giai đoạn 2 (Bài 06 – 09), chúng ta sẽ bước vào chuyên đề sinh tử của mọi hệ thống hạ tầng: Làm Chủ Quản Trị State File, Remote Backend S3/DynamoDB và Chiến Lược Khắc Phục Thảm Họa State Drift.
Bài viết thuộc Series đào tạo Terraform Thực Chiến độc quyền trên ShowTech.vn.