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-file adalah pola multi-environment yang paling bersih.
  • terraform.tfvars untuk 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? →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact