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.
flowchart TD
A["š Default value\ndi deklarasi variable"] -->|prioritas naik| B["š terraform.tfvars"]
B -->|prioritas naik| C["š *.auto.tfvars\ndibaca otomatis"]
C -->|prioritas naik| D["š§ TF_VAR_*\nenvironment variable"]
D -->|prioritas naik| E["ā” -var-file flag"]
E -->|prioritas tertinggi| F["ā” -var flag"]
style A fill:#6b7280,stroke:#4b5563,color:#fff
style B fill:#3b82f6,stroke:#1e40af,color:#fff
style C fill:#3b82f6,stroke:#1e40af,color:#fff
style D fill:#f59e0b,stroke:#d97706,color:#fff
style E fill:#f97316,stroke:#ea580c,color:#fff
style F fill:#ef4444,stroke:#dc2626,color:#fffHierarki 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.
flowchart LR
A["terraform.tfvars\nš Selalu dibaca"] --> C["Terraform\nEngine"]
B["production.auto.tfvars\nš Dibaca otomatis\nberdasarkan abjad"] --> C
D["custom.tfvars\nā” Harus di-flag\n-var-file"] --> C
style A fill:#3b82f6,stroke:#1e40af,color:#fff
style B fill:#10b981,stroke:#059669,color:#fff
style C fill:#f59e0b,stroke:#d97706,color:#fff
style D fill:#8b5cf6,stroke:#6d28d9,color:#fffStruktur 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
Menggunakan terraform.tfvars.json
#
Selain format HCL, Terraform juga mendukung format JSON untuk variable files.
// terraform.tfvars.json
{
"environment": "production",
"instance_type": "t3.medium",
"instance_count": 3,
"tags": {
"Project": "MyApp",
"ManagedBy": "Terraform"
}
}
# terraform.tfvars.json otomatis dibaca, sama seperti terraform.tfvars
terraform plan
# Urutan loading untuk JSON sama dengan HCL:
# 1. terraform.tfvars.json (jika ada, bersama terraform.tfvars)
# 2. *.auto.tfvars.json (alphabetical)
# 3. -var-file flag
Environment-Specific Variable Files #
# Pola umum: satu file tfvars per environment
# environments/
# āāā dev.tfvars
# āāā staging.tfvars
# āāā production.tfvars
terraform plan -var-file="environments/production.tfvars"
terraform apply -var-file="environments/staging.tfvars"
# Di CI/CD, pilih file berdasarkan branch atau parameter
if [ "$ENVIRONMENT" == "production" ]; then
terraform apply -var-file="environments/production.tfvars" -auto-approve
elif [ "$ENVIRONMENT" == "staging" ]; then
terraform apply -var-file="environments/staging.tfvars" -auto-approve
fi
Variable Precedence Deep Dive #
Terraform memiliki urutan prioritas yang spesifik untuk menentukan nilai variable.
VARIABLE PRIORITY (dari rendah ke tinggi):
1. Default value di deklarasi variable
variable "x" { default = "low" }
2. terraform.tfvars (dan terraform.tfvars.json)
x = "medium-low"
3. *.auto.tfvars (dan *.auto.tfvars.json) ā alphabetical
config.auto.tfvars: x = "medium"
4. -var-file flag
terraform plan -var-file="custom.tfvars"
x = "medium-high"
5. -var flag dan TF_VAR_ environment variable
terraform plan -var="x=high"
TF_VAR_x="high" terraform plan
6. Input di prompt (jika tidak ada default)
Terraform akan minta input interaktif
# Contoh: override dalam CI/CD
# Default: terraform.tfvars ā environment = "dev"
# CI/CD override:
terraform plan -var="environment=staging"
# Ini meng-override nilai di terraform.tfvars
# Environment variable override:
export TF_VAR_instance_type="t3.large"
terraform plan
# TF_VAR_instance_type meng-override semua sumber lain
---
## tfvars Security
```bash
# JANGAN commit tfvars yang berisi secret ke Git!
# .gitignore:
*.tfvars
*.tfvars.json
!terraform.tfvars.example
# Untuk shared values (non-sensitive):
# Commit terraform.tfvars.example dengan placeholder
# terraform.tfvars.example (commit ini)
# environment = "dev"
# instance_type = "t3.micro"
# db_password = "CHANGE_ME"
# terraform.tfvars (JANGAN commit)
environment = "production"
instance_type = "m5.large"
db_password = "actually-secret-password"
# Alternatif: gunakan environment variables untuk secret
# export TF_VAR_db_password="secret"
# Terraform akan baca dari TF_VAR_ prefix
Hierarchical Variable Loading #
TERRAFORM VARIABLE LOADING ORDER:
1. Environment variables (TF_VAR_*)
āāā Loaded automatically from shell
2. terraform.tfvars
āāā Auto-loaded jika ada di working directory
3. *.auto.tfvars
āāā Auto-loaded, alphabetical order
4. -var-file=explicit.tfvars
āāā Explicit, bisa specify multiple
5. -var="key=value"
āāā Command line, highest priority
NAMING CONVENTION:
common.tfvars ā Shared values across all envs
dev.tfvars ā Dev-specific values
staging.tfvars ā Staging-specific values
production.tfvars ā Production-specific values
secrets.tfvars ā NEVER commit (in .gitignore)
# Combine multiple var files
terraform apply -var-file="common.tfvars" -var-file="environments/dev.tfvars" -var-file="regions/ap-southeast-1.tfvars"
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? ā