Memahami Konsep Infrastructure as Code (IaC) di DevOps
Pendahuluan: Apa itu Infrastructure as Code (IaC) dan Mengapa Penting?
Bayangkan kamu bekerja di startup yang aplikasinya tiba-tiba viral — seperti jika ingin membangun layanan seperti Tokopedia atau Shopee saat kampanye harbolnas. Server kamu kewalahan, dan kamu harus menambah 50 server baru dalam hitungan jam. Tanpa otomasi, ini bisa memakan waktu berhari-hari dan rentan terhadap kesalahan manusia.
Di sinilah Infrastructure as Code (IaC) hadir sebagai solusi. IaC adalah pendekatan di mana infrastruktur IT — server, jaringan, database, load balancer — dikelola menggunakan kode yang dapat di-versioning, di-review, dan di-otomatis, persis seperti kode aplikasi biasa.
Sebelum IaC, tim ops harus mengkonfigurasi server secara manual melalui antarmuka web atau perintah SSH satu per satu. Pendekatan ini disebut ClickOps — lambat, tidak konsisten, dan sulit direproduksi. IaC mengubah paradigma ini: infrastruktur didefinisikan dalam file teks yang bisa disimpan di Git, di-review lewat pull request, dan di-deploy secara otomatis.
Manfaat utama IaC:
- Konsistensi: Infrastruktur yang sama selalu di-deploy dengan cara yang sama
- Reproducibility: Environment dev, staging, dan production identik
- Kecepatan: Deploy ratusan server dalam menit
- Audit trail: Setiap perubahan tercatat di Git history
- Disaster recovery: Infrastruktur bisa di-rebuild dari nol dalam hitungan menit
Prasyarat dan Setup Lingkungan
Sebelum mencoba contoh-contoh kode di artikel ini, pastikan kamu sudah memiliki:
Tools yang diperlukan:
- Terraform CLI versi >= 1.6.0
- AWS CLI versi >= 2.0
- Ansible versi >= 8.0 (opsional, untuk contoh Ansible)
- Akun AWS (bisa menggunakan Free Tier)
Instalasi Terraform di Linux/macOS:
# Download dan install Terraform
wget https://releases.hashicorp.com/terraform/1.6.0/terraform_1.6.0_linux_amd64.zip
unzip terraform_1.6.0_linux_amd64.zip
sudo mv terraform /usr/local/bin/
# Verifikasi instalasi
terraform version
# Output: Terraform v1.6.0
Setup AWS credentials:
# Install AWS CLI
pip install awscli
# Konfigurasi credentials
aws configure
# AWS Access Key ID [None]: <masukkan access key kamu>
# AWS Secret Access Key [None]: <masukkan secret key kamu>
# Default region name [None]: ap-southeast-1
# Default output format [None]: json
# Verifikasi konfigurasi
aws sts get-caller-identity
# Output: {"UserId": "...", "Account": "123456789", "Arn": "arn:aws:iam::..."}
Instalasi Ansible:
# Ubuntu/Debian
sudo apt update && sudo apt install -y ansible
# macOS
brew install ansible
# Verifikasi instalasi
ansible --version
# Output: ansible [core 2.15.x]
Prinsip-Prinsip Kunci dalam IaC
Memahami prinsip IaC membantu kamu menulis kode infrastruktur yang lebih baik dan maintainable.
1. Idempotency
Menjalankan kode IaC berkali-kali harus menghasilkan state yang sama. Jika server sudah ada, jangan buat lagi — update jika perlu.
2. Declarative vs Imperative
Ada dua pendekatan dalam IaC:
Declarative — kamu mendeskripsikan apa yang kamu inginkan, bukan bagaimana caranya:
# Terraform (declarative)
resource "aws_instance" "web_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = "KamusNgoding-WebServer"
Environment = "production"
}
}
Imperative — kamu mendeskripsikan langkah-langkah yang harus dilakukan:
# Ansible (lebih imperative)
- name: Install nginx
apt:
name: nginx
state: present
- name: Start nginx service
service:
name: nginx
state: started
enabled: yes
3. Version Control Everything
Semua file konfigurasi infrastruktur harus masuk ke Git:
# Buat struktur repository IaC
mkdir -p infrastructure/{terraform/modules/{networking,compute},ansible/{playbooks,inventory}}
cd infrastructure
# Struktur repository IaC yang baik
# infrastructure/
# ├── terraform/
# │ ├── main.tf
# │ ├── variables.tf
# │ ├── outputs.tf
# │ └── modules/
# │ ├── networking/
# │ └── compute/
# ├── ansible/
# │ ├── playbooks/
# │ └── inventory/
# └── .gitignore
# Buat .gitignore untuk IaC
cat > .gitignore << 'EOF'
# Terraform state files (sensitif!)
*.tfstate
*.tfstate.backup
.terraform/
# Secrets
*.pem
*.key
.env
# Ansible
*.retry
EOF
4. Immutable Infrastructure
Daripada mengupdate server yang sudah ada, lebih baik buat server baru dengan konfigurasi baru lalu hapus yang lama. Ini menghilangkan “configuration drift” — kondisi di mana server prod dan dev perlahan menjadi berbeda.
Alat-Alat Populer untuk IaC: Terraform, Ansible, dan Lainnya
Terraform
Terraform dari HashiCorp adalah tools IaC paling populer untuk provisioning infrastruktur cloud. Terraform mendukung AWS, GCP, Azure, dan ratusan provider lainnya.
# main.tf — Membuat VPC dan subnet di AWS
# Jalankan: terraform init && terraform plan && terraform apply
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
}
data "aws_availability_zones" "available" {
state = "available"
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags = {
Name = "${var.project_name}-vpc"
}
}
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Name = "${var.project_name}-public-subnet-${count.index + 1}"
}
}
# variables.tf
variable "aws_region" {
description = "AWS region untuk deployment"
type = string
default = "ap-southeast-1" # Singapore — dekat Indonesia
}
variable "project_name" {
description = "Nama project"
type = string
default = "kamusngoding"
}
# outputs.tf
output "vpc_id" {
description = "ID dari VPC yang dibuat"
value = aws_vpc.main.id
}
output "public_subnet_ids" {
description = "ID subnet publik"
value = aws_subnet.public[*].id
}
Cara menjalankan:
# 1. Inisialisasi Terraform (download providers)
terraform init
# 2. Preview perubahan
terraform plan
# 3. Apply perubahan
terraform apply
# Ketik 'yes' saat diminta konfirmasi
# Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
# 4. Lihat output
terraform output vpc_id
Ansible
Ansible lebih cocok untuk konfigurasi server dan deployment aplikasi setelah infrastruktur siap.
# inventory/hosts.ini
[webservers]
web1 ansible_host=10.0.0.10 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa
web2 ansible_host=10.0.0.11 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa
[all:vars]
ansible_python_interpreter=/usr/bin/python3
# playbook/setup-webserver.yml
# Jalankan: ansible-playbook -i inventory/hosts.ini playbook/setup-webserver.yml
---
- name: Setup Web Server Production
hosts: webservers
become: yes
vars:
app_user: "deploy"
app_dir: "/var/www/kamusngoding"
tasks:
- name: Update apt cache
apt:
update_cache: yes
cache_valid_time: 3600
- name: Install dependencies
apt:
name:
- nginx
- nodejs
- npm
- git
state: present
- name: Create application directory
file:
path: "{{ app_dir }}"
state: directory
owner: "{{ app_user }}"
mode: '0755'
- name: Deploy Nginx config
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/sites-available/kamusngoding
notify: Reload nginx
handlers:
- name: Reload nginx
service:
name: nginx
state: reloaded
# Cara menjalankan Ansible playbook
# Test koneksi ke semua host dulu
ansible -i inventory/hosts.ini webservers -m ping
# Jalankan playbook dengan dry-run (--check)
ansible-playbook -i inventory/hosts.ini playbook/setup-webserver.yml --check
# Apply sesungguhnya
ansible-playbook -i inventory/hosts.ini playbook/setup-webserver.yml
# Output:
# PLAY RECAP *******
# web1 : ok=5 changed=3 unreachable=0 failed=0
# web2 : ok=5 changed=3 unreachable=0 failed=0
Tools IaC Lainnya
| Tool | Kegunaan | Bahasa |
|---|---|---|
| Pulumi | IaC dengan bahasa pemrograman umum | Python, TypeScript, Go |
| AWS CDK | IaC khusus AWS | TypeScript, Python |
| CloudFormation | IaC native AWS | YAML/JSON |
| Helm | Package manager untuk Kubernetes | YAML |
Mengintegrasikan IaC dalam Pipeline CI/CD
IaC paling powerful ketika diintegrasikan ke dalam pipeline CI/CD. Setiap perubahan infrastruktur bisa di-review, di-test, dan di-apply secara otomatis — mirip seperti cara menjalankan tes otomatis dengan GitHub Actions untuk kode aplikasi.
# .github/workflows/terraform.yml
name: Terraform Infrastructure CI/CD
on:
push:
branches: [main]
paths: ['infrastructure/**']
pull_request:
paths: ['infrastructure/**']
env:
TF_VERSION: '1.6.0'
AWS_REGION: 'ap-southeast-1'
jobs:
terraform-plan:
name: Terraform Plan
runs-on: ubuntu-latest
defaults:
run:
working-directory: infrastructure/terraform
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TF_VERSION }}
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Terraform Init
run: terraform init
- name: Terraform Format Check
run: terraform fmt -check -recursive
- name: Terraform Validate
run: terraform validate
- name: Terraform Plan
run: terraform plan -out=tfplan
- name: Upload plan artifact
uses: actions/upload-artifact@v4
with:
name: terraform-plan
path: infrastructure/terraform/tfplan
terraform-apply:
name: Terraform Apply
needs: terraform-plan
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
environment: production # Requires manual approval
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TF_VERSION }}
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Terraform Init
working-directory: infrastructure/terraform
run: terraform init
- name: Download plan
uses: actions/download-artifact@v4
with:
name: terraform-plan
path: infrastructure/terraform/
- name: Terraform Apply
working-directory: infrastructure/terraform
run: terraform apply -auto-approve tfplan
Pola ini — Plan on PR, Apply on merge — adalah best practice IaC dalam CI/CD. Tim bisa mereview perubahan infrastruktur sebelum di-apply, mengurangi risiko outage produksi. Konsep ini mirip dengan yang dijelaskan dalam membangun CI/CD Pipeline untuk aplikasi Node.js dengan GitHub Actions.
Contoh Kasus Nyata: Deploy Infrastruktur Web dengan Terraform
Mari kita lihat contoh nyata: deploy infrastruktur untuk web application sederhana dengan load balancer, auto-scaling, dan database.
# modules/compute/main.tf — Auto Scaling Group
# Prasyarat: VPC dan subnet sudah dibuat (lihat contoh main.tf di atas)
# Jalankan dari direktori root: terraform apply -target=module.compute
variable "project_name" { type = string }
variable "ami_id" { type = string }
variable "instance_type" { default = "t3.micro" }
variable "subnet_ids" { type = list(string) }
variable "artifact_bucket" { type = string }
resource "aws_security_group" "app" {
name_prefix = "${var.project_name}-app-"
vpc_id = data.aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_launch_template" "app" {
name_prefix = "${var.project_name}-"
image_id = var.ami_id
instance_type = var.instance_type
user_data = base64encode(<<-EOF
#!/bin/bash
apt-get update
apt-get install -y nginx awscli
# Deploy app dari S3
aws s3 cp s3://${var.artifact_bucket}/app.tar.gz /tmp/
tar -xzf /tmp/app.tar.gz -C /var/www/html
systemctl start nginx
systemctl enable nginx
EOF
)
vpc_security_group_ids = [aws_security_group.app.id]
tag_specifications {
resource_type = "instance"
tags = {
Name = "${var.project_name}-app-server"
}
}
}
resource "aws_autoscaling_group" "app" {
desired_capacity = 2
max_size = 10
min_size = 1
target_group_arns = [aws_lb_target_group.app.arn]
vpc_zone_identifier = var.subnet_ids
launch_template {
id = aws_launch_template.app.id
version = "$Latest"
}
tag {
key = "Name"
value = "${var.project_name}-asg"
propagate_at_launch = true
}
}
resource "aws_autoscaling_policy" "scale_up" {
name = "${var.project_name}-scale-up"
autoscaling_group_name = aws_autoscaling_group.app.name
adjustment_type = "ChangeInCapacity"
scaling_adjustment = 2
cooldown = 300
}
resource "aws_cloudwatch_metric_alarm" "high_cpu" {
alarm_name = "${var.project_name}-high-cpu"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 2
metric_name = "CPUUtilization"
namespace = "AWS/EC2"
period = 120
statistic = "Average"
threshold = 80
alarm_actions = [aws_autoscaling_policy.scale_up.arn]
}
Dengan konfigurasi ini, jika CPU usage naik di atas 80% (misalnya saat traffic spike seperti flash sale di aplikasi e-commerce), sistem otomatis akan menambah 2 server baru.
Troubleshooting: Error yang Sering Muncul saat Bekerja dengan IaC
Error: “Error acquiring the state lock”
Penyebab: Terraform menggunakan state locking untuk mencegah dua operasi berjalan bersamaan. Error ini muncul jika proses sebelumnya crash atau state lock tidak dilepas dengan benar.
Solusi:
# Lihat detail lock ID dari pesan error, lalu jalankan:
terraform force-unlock <LOCK_ID>
# Jika menggunakan S3 backend, cek DynamoDB untuk lock yang tersangkut
aws dynamodb scan \
--table-name terraform-state-lock \
--filter-expression "attribute_exists(LockID)"
# Force unlock (gunakan dengan hati-hati — pastikan tidak ada proses lain yang berjalan!)
terraform force-unlock -force <LOCK_ID>
# Output jika berhasil:
# Do you really want to force-unlock?
# Terraform will remove the lock on the remote state.
# yes
# Terraform state has been successfully unlocked!
Error: “Error: Provider configuration not present”
Penyebab: Terraform tidak bisa menemukan konfigurasi provider (misalnya AWS credentials) saat menjalankan terraform apply di environment CI/CD.
Solusi:
# Pastikan environment variables tersedia sebelum menjalankan terraform
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
export AWS_DEFAULT_REGION="ap-southeast-1"
# Verifikasi credentials aktif
aws sts get-caller-identity
# Output yang benar:
# {
# "UserId": "AIXXXXXXXXXXXXXXXXX",
# "Account": "123456789012",
# "Arn": "arn:aws:iam::123456789012:user/terraform-user"
# }
# Baru jalankan terraform
terraform apply
Error: “Failed to load module” saat terraform init
Penyebab: Terraform tidak bisa menemukan atau mengakses modul yang dipanggil di konfigurasi, bisa karena path salah atau koneksi internet terputus.
Solusi:
# Periksa path modul di main.tf
# Contoh yang salah:
# source = "./module/compute" ❌
# Contoh yang benar:
# source = "./modules/compute" ✓
# Jika modul dari registry, pastikan koneksi internet aktif lalu jalankan ulang:
terraform init -upgrade
# Output jika berhasil:
# Initializing modules...
# - compute in modules/compute
# Terraform has been successfully initialized!
Error: “ResourceAlreadyExists” atau resource sudah ada di cloud
Penyebab: Terraform mencoba membuat resource yang sudah ada secara manual di cloud (tidak dikelola oleh Terraform), sehingga terjadi konflik.
Solusi:
# Import resource yang sudah ada ke Terraform state
# Format: terraform import <resource_type>.<resource_name> <resource_id_di_cloud>
# Contoh import EC2 instance yang sudah ada:
terraform import aws_instance.web_server i-0123456789abcdef0
# Contoh import S3 bucket:
terraform import aws_s3_bucket.app_bucket nama-bucket-kamu
# Setelah import, pastikan konfigurasi .tf kamu sesuai dengan resource yang ada
terraform plan
# Jika output: "No changes. Infrastructure is up-to-date." — berhasil!
Pertanyaan yang Sering Diajukan
Apakah IaC hanya untuk cloud, atau bisa untuk server on-premise?
IaC bisa digunakan untuk keduanya. Terraform mendukung provider untuk VMware, Proxmox, dan platform virtualisasi on-premise lainnya. Ansible bahkan lebih fleksibel — bisa mengkonfigurasi server fisik maupun virtual di mana saja selama bisa diakses via SSH. Jadi, meski cloud adalah use case paling umum, IaC sama bermanfaatnya untuk data center tradisional.
Apa perbedaan utama antara Terraform dan Ansible, dan kapan sebaiknya menggunakan masing-masing?
Terraform unggul dalam provisioning infrastruktur — membuat dan menghapus resource cloud seperti VPC, EC2, database, dan load balancer. Ansible lebih cocok untuk konfigurasi dan manajemen software di server yang sudah ada, seperti menginstall paket, mendeploy aplikasi, atau mengatur konfigurasi sistem. Dalam praktiknya, keduanya sering digunakan bersama: Terraform membuat server, lalu Ansible mengkonfigurasinya.
Bagaimana cara menyimpan secrets (password, API key) dengan aman di IaC?
Jangan pernah menyimpan secrets langsung di file .tf atau di Git. Ada beberapa pendekatan yang aman: gunakan environment variables untuk credentials sementara, AWS Secrets Manager atau HashiCorp Vault untuk secrets yang dikelola secara terpusat, atau Terraform Cloud yang menyediakan penyimpanan variabel terenkripsi. Untuk CI/CD, simpan secrets di GitHub Actions Secrets dan inject sebagai environment variable saat pipeline berjalan.
Berapa lama waktu yang dibutuhkan untuk belajar Terraform dari nol?
Dengan latihan konsisten, konsep dasar Terraform (resource, variable, output, state) bisa dipahami dalam 1-2 minggu. Untuk bisa produktif membangun infrastruktur sederhana di AWS, biasanya butuh 1-2 bulan. Yang paling penting adalah langsung praktik — buat akun AWS Free Tier, ikuti tutorial resmi Terraform, dan coba deploy infrastruktur sederhana sendiri.
Apakah perlu menguasai satu cloud provider dulu sebelum belajar IaC?
Tidak harus, tapi sangat membantu. Memahami konsep dasar cloud (apa itu VPC, EC2, S3, IAM) akan mempercepat proses belajar IaC karena kamu sudah tahu apa yang sedang kamu otomasi. Jika mulai dari nol, belajar konsep cloud dasar AWS selama 2-3 minggu terlebih dahulu, kemudian mulai eksplorasi Terraform — prosesnya akan jauh lebih lancar.
Kesimpulan: Masa Depan Infrastruktur Otomatis
Infrastructure as Code bukan lagi “nice to have” — ini adalah keahlian wajib bagi engineer modern. Di era cloud-native, kemampuan untuk mendefinisikan, memversioning, dan mengotomasi infrastruktur adalah yang membedakan tim yang bisa scale dari yang tidak.
Kita sudah membahas prinsip-prinsip IaC (idempotency, pendekatan deklaratif, infrastruktur imut), tools utama (Terraform untuk provisioning, Ansible untuk konfigurasi), cara mengintegrasikan IaC ke pipeline CI/CD dengan GitHub Actions, hingga kasus nyata deploy infrastruktur auto-scaling.
Tren ke depan sangat menarik: GitOps membawa IaC satu level lebih jauh dengan menjadikan Git sebagai single source of truth untuk seluruh sistem. Tools seperti ArgoCD dan Flux secara otomatis menyinkronkan state Git dengan state cluster Kubernetes. Jika kamu ingin membangun aplikasi berskala besar seperti layanan streaming atau e-commerce, menguasai IaC adalah investasi karir yang sangat berharga.
Selamat bereksperimen dan terus tingkatkan skill infrastruktur kamu! Jika ada pertanyaan atau ingin eksplorasi topik DevOps lainnya, jangan ragu untuk menjelajahi artikel-artikel lain di KamusNgoding — komunitas developer Indonesia ada untuk saling mendukung.