Apa itu Infrastructure as Code?
Infrastructure as Code (IaC) adalah praktik mendefinisikan dan mengelola infrastruktur menggunakan file konfigurasi, bukan manual setup via console/GUI.
Manfaat IaC
- Reproducible — Buat environment identik kapan saja
- Version controlled — Track perubahan via Git
- Reviewable — PR review untuk perubahan infra
- Automated — Bisa dijalankan dari CI/CD
Terraform (HCL)
# main.tf
provider "aws" {
region = "ap-southeast-1"
}
resource "aws_instance" "web" {
ami = "ami-0abcdef1234567890"
instance_type = "t3.micro"
tags = {
Name = "web-server"
Environment = "production"
}
}
resource "aws_security_group" "web" {
name = "web-sg"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
Terraform Workflow
# Initialize
terraform init
# Preview perubahan
terraform plan
# Apply perubahan
terraform apply
# Hapus semua resource
terraform destroy
# State disimpan di terraform.tfstate (jangan edit manual!)
Terraform State Management
State file adalah sumber kebenaran Terraform tentang apa yang sudah di-provision. Ini topik paling sering jadi masalah di production.
Local vs Remote Backend
# BURUK: state lokal — tidak bisa kolaborasi, bisa hilang
# terraform.tfstate ada di laptop developer
# BAIK: remote backend dengan locking
# backend.tf
terraform {
backend "s3" {
bucket = "mycompany-terraform-state"
key = "prod/app.tfstate"
region = "ap-southeast-1"
dynamodb_table = "terraform-locks" # state locking
encrypt = true # encryption-at-rest
}
}
# Alternatif:
# - GCS bucket untuk GCP
# - Azure Storage Account untuk Azure
# - Terraform Cloud (managed)
State Locking
Tanpa locking, dua engineer yang apply bersamaan bisa merusak state. DynamoDB table (atau setara) memastikan hanya satu terraform apply yang jalan pada satu waktu.
terraform import: Adopsi Resource yang Sudah Ada
# Resource dibuat manual via console, sekarang mau dikelola IaC
terraform import aws_instance.web i-0abc123def456
# Terraform sekarang tracking resource ini di state
# Tulis config HCL yang match, lalu plan harus menunjukkan "no changes"
Drift Detection
Seseorang mengubah resource via console → state tidak match reality lagi (drift). terraform plan akan menunjukkan perubahan yang kamu tidak niatkan — investigasi sebelum apply membabi buta.
⚠️ State Berisi Secrets dalam Plain Text
Password RDS, API key, dan semua sensitive output tersimpan plain text di state file. Karena itu:
- Aktifkan
encrypt = truedi backend S3 - Batasi akses bucket state (IAM policy ketat)
- Jangan pernah commit
terraform.tfstateke Git - Gunakan
sensitive = truepada output agar tidak muncul di CI log
Workspaces untuk Multi-Environment
terraform workspace new staging
terraform workspace new production
terraform workspace select staging
terraform apply -var-file=staging.tfvars
# Setiap workspace punya state file terpisah di backend
# Gunakan ${terraform.workspace} di config untuk beda per env
Ansible (Configuration Management)
# playbook.yml
- hosts: web_servers
become: yes
tasks:
- name: Install Nginx
apt:
name: nginx
state: present
- name: Copy Nginx config
template:
src: nginx.conf.j2
dest: /etc/nginx/sites-available/default
notify: Restart Nginx
handlers:
- name: Restart Nginx
service:
name: nginx
state: restarted
Idempotency: Prinsip Inti Configuration Management
Idempotent artinya menjalankan playbook 10 kali menghasilkan state akhir yang sama dengan menjalankan 1 kali. Modul Ansible (apt, template, service, dll) cek state terlebih dulu — hanya bertindak jika beda.
# BURUK: shell command non-idempotent
- shell: echo "127.0.0.1 myhost" >> /etc/hosts
# Dijalankan 5 kali → 5 baris duplikat!
# BAIK: modul idempotent
- lineinfile:
path: /etc/hosts
line: "127.0.0.1 myhost"
state: present
# Dijalankan 5 kali → 1 baris (cek dulu)
Tanpa idempotency, re-run untuk fix partial failure jadi berbahaya. Itulah kenapa Ansible/Puppet/Chef dirancang deklaratif dengan state desired, bukan sekumpulan command imperatif.