Infrastructure as Code dengan Terraform

Foto oleh HashiCorp

Foto oleh HashiCorp
Infrastructure as Code dengan Terraform telah mengubah cara tim DevOps melakukan provisioning dan pengelolaan sumber daya cloud. Alih-alih mengklik satu per satu di console cloud atau menjalankan skrip ad-hoc, Terraform memungkinkan Anda mendeskripsikan seluruh infrastruktur dalam file HCL yang mudah dibaca, dapat di-review, di-versioning, dan digunakan ulang di setiap environment — dari local dev hingga production multi-region.
Terraform adalah tool deklaratif: Anda mendeskripsikan kondisi akhir infrastruktur yang diinginkan, lalu Terraform menentukan cara mencapainya. Alurnya selalu sama — tulis konfigurasi dalam HCL, jalankan terraform plan untuk melihat perubahan, dan terraform apply untuk mengeksekusinya. Kekuatan sesungguhnya ada pada cara Terraform melacak semua yang dikelolanya melalui state file.
Setiap konfigurasi Terraform dibangun dari resource block yang memetakan langsung ke objek API cloud — aws_instance, google_storage_bucket, azurerm_virtual_network. Variable, output, dan data source melengkapi bahasa ini. Block backend memberitahu Terraform di mana menyimpan state file — selalu gunakan remote backend (S3, GCS, Terraform Cloud) agar state dapat dibagi ke seluruh tim.
# main.tf — Provision an AWS EC2 instance
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "my-terraform-state"
key = "prod/ec2/terraform.tfstate"
region = "ap-southeast-1"
}
}
provider "aws" {
region = var.aws_region
}
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
tags = {
Name = "web-server"
Environment = var.environment
ManagedBy = "Terraform"
}
}
variable "aws_region" { default = "ap-southeast-1" }
variable "instance_type" { default = "t3.micro" }
variable "environment" { default = "production" }Module adalah paket resource Terraform yang mandiri dan dapat digunakan ulang. Module menerima variable input dan mengekspos output, memungkinkan Anda mengenkapsulasi infrastruktur kompleks seperti VPC dengan subnet publik dan privat di balik antarmuka yang bersih. Module yang dirancang dengan baik membuat replikasi environment menjadi mudah — buat staging environment yang mencerminkan production hanya dengan satu pemanggilan module.
Module VPC yang baik menerima cidr_block, nama environment, dan daftar availability zone. Module ini membuat VPC, subnet publik dan privat, route table, serta internet gateway — mengekspos VPC ID dan subnet ID untuk digunakan module lain. Meta-argument count membuat subnet menjadi dinamis: satu subnet per AZ tanpa duplikasi kode.
# modules/vpc/main.tf — Reusable VPC module
variable "cidr_block" {}
variable "environment" {}
variable "azs" { type = list(string) }
resource "aws_vpc" "main" {
cidr_block = var.cidr_block
enable_dns_hostnames = true
tags = { Name = "${var.environment}-vpc" }
}
resource "aws_subnet" "public" {
count = length(var.azs)
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.cidr_block, 8, count.index)
availability_zone = var.azs[count.index]
tags = { Name = "${var.environment}-public-${count.index}" }
}
output "vpc_id" { value = aws_vpc.main.id }
output "subnet_ids" { value = aws_subnet.public[*].id }
# Usage in root module
module "vpc" {
source = "./modules/vpc"
cidr_block = "10.0.0.0/16"
environment = "prod"
azs = ["ap-southeast-1a", "ap-southeast-1b"]
}Selalu jalankan terraform plan sebelum apply di CI/CD dan tinjau hasilnya. Tambahkan -detailed-exitcode untuk membedakan 'tidak ada perubahan' (exit 0) dari 'ada perubahan tertunda' (exit 2) — ini memungkinkan Anda melewati apply yang tidak diperlukan dan mempercepat pipeline.
State Terraform adalah apa yang memungkinkan tool ini mengetahui apa yang dikelola dan apa yang berubah sejak apply terakhir. Remote state di bucket S3 dengan DynamoDB locking mencegah penulisan bersamaan yang dapat merusak infrastruktur Anda. Workspace adalah cara ergonomis untuk mempertahankan state file terpisah untuk staging dan production sambil berbagi codebase konfigurasi yang sama.
Daripada menduplikasi konfigurasi untuk setiap environment, gunakan file .tfvars dikombinasikan dengan workspace. Cukup satu terraform apply -var-file=environments/production.tfvars untuk memilih value yang tepat. Interpolasi terraform.workspace memungkinkan Anda menyematkan nama environment secara otomatis ke dalam nama resource dan tag.
# terraform.tfvars — Environment-specific values
environment = "production"
aws_region = "ap-southeast-1"
instance_type = "t3.medium"
# Workspace-based state isolation
# terraform workspace new staging
# terraform workspace select production
# terraform apply -var-file="environments/${terraform.workspace}.tfvars"State file Terraform berisi atribut resource dalam plaintext, termasuk password dan private key. Aktifkan enkripsi state (Terraform Cloud mengenkripsi secara default; backend S3 menggunakan KMS). Jangan pernah commit file .tfvars yang berisi secret — gunakan environment variable atau secrets manager seperti HashiCorp Vault atau AWS Secrets Manager.
Menjalankan Terraform di CI/CD memastikan setiap perubahan melalui plan → review → apply dengan audit trail yang lengkap. GitHub Actions, GitLab CI, dan Atlantis adalah pilihan yang populer. Pola utamanya adalah: validasi dan plan di setiap pull request (tampilkan hasil plan sebagai komentar PR), dan apply otomatis hanya saat merge ke branch main.
Workflow GitHub Actions Terraform standar memiliki empat langkah: checkout → terraform init → terraform validate → terraform plan pada pull request, dan menambahkan terraform apply pada push ke main. Gunakan autentikasi berbasis OIDC ke AWS atau GCP untuk menghindari penyimpanan kredensial jangka panjang sebagai GitHub Secrets.
# .github/workflows/terraform.yml — CI/CD for Terraform
name: Terraform CI/CD
on:
push:
branches: [main]
pull_request:
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: "1.7.0"
- name: Terraform Init
run: terraform init
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Terraform Validate
run: terraform validate
- name: Terraform Plan
run: terraform plan -out=tfplan
- name: Terraform Apply
if: github.ref == 'refs/heads/main'
run: terraform apply -auto-approve tfplanSebelum melanjutkan, mari perjelas beberapa terminologi inti Terraform yang akan sering Anda temui: HCL, state file, modules, plan, workspaces, and providers.
Ikuti praktik-praktik ini untuk Terraform level production: pin versi provider dengan ~> untuk menghindari breaking change, gunakan remote state dengan locking, susun kode ke dalam module sejak awal, tag setiap resource dengan environment dan ManagedBy=Terraform, dan jalankan terraform fmt serta tflint di CI untuk menjaga konsistensi kode. Kombinasikan Terraform dengan Ansible untuk configuration management — Terraform menyediakan infrastruktur, Ansible mengonfigurasi software di atasnya.