File & Environment #
Mendeklarasikan variable hanyalah separuh pekerjaan. Separuh lainnya adalah strategi bagaimana nilai variable itu dikelola — di file mana, oleh siapa, bagaimana yang sensitif diamankan, dan bagaimana memastikan setiap environment mendapat nilai yang tepat tanpa duplikasi konfigurasi yang berlebihan. Tanpa strategi yang jelas, proyek multi-environment cepat menjadi kumpulan file tfvars yang saling membingungkan.
Hierarki File tfvars #
Terraform membaca file variable dalam urutan tertentu. Memahami hierarki ini mencegah kebingungan tentang nilai mana yang akhirnya digunakan.
URUTAN PEMBACAAN FILE VARIABLE (dari terendah ke tertinggi):
1. default di deklarasi variable
2. terraform.tfvars (auto-loaded, jika ada)
3. terraform.tfvars.json (auto-loaded, jika ada)
4. *.auto.tfvars (auto-loaded, diurutkan alphabetically)
5. *.auto.tfvars.json (auto-loaded, diurutkan alphabetically)
6. -var-file="file.tfvars" (via flag, urutan flag menentukan prioritas)
7. -var="key=value" (via flag, prioritas tertinggi)
Nilai yang dibaca lebih akhir MENIMPA nilai sebelumnya.
Struktur File tfvars untuk Multi-Environment #
Pola yang paling bersih untuk multi-environment adalah satu file per environment, dipilih saat apply dengan flag -var-file.
environments/
├── dev.tfvars
├── staging.tfvars
└── production.tfvars
# environments/dev.tfvars
environment = "dev"
instance_type = "t3.micro"
instance_count = 1
database_config = {
instance_class = "db.t3.micro"
allocated_storage = 20
multi_az = false
backup_retention = 1
}
tags = {
Environment = "dev"
CostCenter = "engineering"
ManagedBy = "terraform"
}
# environments/production.tfvars
environment = "production"
instance_type = "t3.medium"
instance_count = 3
database_config = {
instance_class = "db.r5.large"
allocated_storage = 500
multi_az = true
backup_retention = 30
}
tags = {
Environment = "production"
CostCenter = "engineering"
ManagedBy = "terraform"
}
# Gunakan saat apply
terraform apply -var-file="environments/dev.tfvars"
terraform apply -var-file="environments/production.tfvars"
File terraform.tfvars untuk Nilai Default Tim #
terraform.tfvars dibaca otomatis dan cocok untuk nilai yang berlaku di semua environment — nilai default yang tidak perlu dioverride per environment.
# terraform.tfvars — nilai default, di-commit ke Git
# (jangan simpan secret di sini)
region = "ap-southeast-1"
owner = "platform-team"
common_tags = {
Project = "my-app"
ManagedBy = "terraform"
Repository = "github.com/org/infrastructure"
}
# Nilai yang sama di semua environment
enable_monitoring = true
log_retention_days = 30
Environment Variable TF_VAR_* #
Environment variable dengan prefix TF_VAR_ adalah cara yang tepat untuk mengoper nilai yang berbeda-beda di setiap konteks — terutama di CI/CD pipeline dan untuk secret.
# Terraform membaca TF_VAR_<nama_variable> otomatis
# Nama variable harus EXACT MATCH (case-sensitive)
export TF_VAR_environment="production"
export TF_VAR_instance_type="t3.medium"
# Untuk variable dengan tipe kompleks, gunakan format HCL/JSON
export TF_VAR_database_config='{"instance_class":"db.r5.large","allocated_storage":500,"multi_az":true}'
terraform apply
# Terraform membaca TF_VAR_* dan menggunakannya sebagai nilai variable
# Contoh penggunaan di GitHub Actions CI/CD
name: Terraform Apply Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
- name: Terraform Init
run: terraform init
- name: Terraform Apply
env:
# Nilai non-sensitif dari tfvars file
TF_VAR_environment: "production"
# Secret dari GitHub Secrets — tidak pernah masuk ke kode
TF_VAR_db_password: ${{ secrets.DB_PASSWORD }}
TF_VAR_api_key: ${{ secrets.API_KEY }}
# AWS credentials
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: terraform apply -auto-approve -var-file="environments/production.tfvars"
Memisahkan Secret dari Konfigurasi Biasa #
Secret tidak boleh di-commit ke Git, bahkan di file .tfvars sekalipun. Ada dua pendekatan utama.
# PENDEKATAN 1: Baca secret dari AWS Secrets Manager via data source
# Secret dikelola di luar Terraform, Terraform hanya membacanya
data "aws_secretsmanager_secret_version" "db_credentials" {
secret_id = "production/database/credentials"
}
locals {
db_credentials = jsondecode(
data.aws_secretsmanager_secret_version.db_credentials.secret_string
)
}
resource "aws_db_instance" "main" {
username = local.db_credentials.username
password = local.db_credentials.password
# ... atribut lainnya
}
# PENDEKATAN 2: Variable sensitive diisi via TF_VAR_* environment variable
# Secret dikelola di secrets manager CI/CD (GitHub Secrets, HashiCorp Vault)
# dan dioper ke Terraform sebagai environment variable
variable "db_password" {
type = string
sensitive = true
# Tidak ada default — Terraform akan error jika TF_VAR_db_password tidak di-set
}
resource "aws_db_instance" "main" {
password = var.db_password
}
Anti-Pattern yang Harus Dihindari #
# ANTI-PATTERN 1: Secret di file .tfvars yang di-commit ke Git
# production.tfvars
db_password = "super-secret-password" # ✗ Bocor ke semua yang akses repo
api_key = "sk-prod-abc123def456" # ✗ Tersimpan di Git history selamanya
# ANTI-PATTERN 2: Satu file tfvars untuk semua environment
# all-environments.tfvars
dev_instance_type = "t3.micro" # ✗ File jadi besar dan membingungkan
prod_instance_type = "t3.medium"
dev_db_class = "db.t3.micro"
prod_db_class = "db.r5.large"
# Lebih baik: file terpisah per environment
# ANTI-PATTERN 3: Nilai hardcode di konfigurasi padahal seharusnya variable
resource "aws_instance" "web" {
instance_type = "t3.micro" # ✗ Hardcode — tidak bisa berbeda per environment
}
# Lebih baik: instance_type = var.instance_type
Ringkasan #
- Satu file tfvars per environment (
dev.tfvars,staging.tfvars,production.tfvars) yang dipilih dengan-var-fileadalah pola multi-environment yang paling bersih.terraform.tfvarsuntuk nilai default tim yang berlaku di semua environment — di-commit ke Git, tidak mengandung secret.TF_VAR_*environment variable untuk nilai yang berbeda per context di CI/CD dan untuk semua secret.- Secret tidak masuk ke file tfvars yang di-commit ke Git — gunakan
TF_VAR_*dari secrets manager atau baca langsung dari AWS Secrets Manager via data source.- Hierarki prioritas: flag CLI > tfvars file > auto-loaded tfvars > env var > default — nilai yang lebih spesifik selalu menang.
- Variable sensitive tanpa default memaksa nilai selalu diberikan secara eksplisit — Terraform akan error jika tidak ada nilai, mencegah lupa mengisi secret.
← Sebelumnya: Type & Validation Berikutnya: Apa itu Output? →