L
Infrastructure as Code (IaC) β€’ Literally Web ID

Implementasi Infrastructure as Code (IaC) Skala Produksi Menggunakan Terraform & AWS

⏱️ 15 menit baca β€’ πŸ“… 14 Oct 2026 β€’ πŸ‘οΈ 1 views
Implementasi Infrastructure as Code (IaC) Skala Produksi Menggunakan Terraform & AWS

1. Konteks Industri & Analisis Akar Masalah

Dalam lanskap pengembangan web modern dan rekayasa infrastruktur enterprise, kecepatan rilis (time-to-market) dan keandalan sistem (reliability) adalah dua metrik krusial yang menentukan kesuksesan bisnis. Secara historis, provisioning server, konfigurasi jaringan, setup database, hingga pengaturan load balancer dilakukan secara manual melalui konsol AWS atau menggunakan skrip Bash yang rentan terhadap human error. Pendekatan manual ini menciptakan apa yang dikenal sebagai Configuration Driftβ€”kondisi di mana dokumentasi infrastruktur tidak lagisinkron dengan kondisi aktual di cloud.

Bottleneck terbesar dari infrastruktur manual adalah ketiadaan audit trail yang jelas dan ketidakmampuan untuk mereplikasi lingkungan (staging, development, production) secara identik. Ketika terjadi kegagalan sistem pada aplikasi berbasis web yang menopang arsitektur kompleks (meliputi Nginx, PHP-FPM/Node.js backend, database MySQL/MariaDB berklaster, Redis caching, hingga sistem queue seperti RabbitMQ atau SQS yang diatur Supervisor), pemulihan manual membutuhkan waktu berjam-jam, memicu kerugian finansial yang masif.

Sebelum adopsi Infrastructure as Code (IaC) menggunakan Terraform, tim infrastruktur sering kali menghadapi masalah:

  • Inkonsistensi Lingkungan: Server staging menggunakan spesifikasi sistem operasi atau modul PHP yang berbeda dengan production, menyebabkan bug lolos ke pengguna akhir.
  • Ketergantungan pada Individu: Hanya engineer senior tertentu yang tahu cara merangkai routing VPC, subnet publik/privat, dan aturan Security Group.
  • Risiko Keamanan Tinggi: Sering terjadi over-privileged access karena pembuatan resource dilakukan secara tergesa-gesa melalui web UI AWS Console.

Setelah menerapkan Terraform bersama AWS, seluruh infrastruktur bertransformasi menjadi kode yang deklaratif, version-controlled, dan dapat diaudit. Perubahan arsitektur dari web server tunggal menjadi sistem auto-scaling berbasis Application Load Balancer, ECS/EC2 instances, dengan S3 sebagai storage asset statis dan Cloudflare sebagai edge CDN, dapat direplikasi hanya dalam hitungan menit menggunakan perintah terraform apply.


2. Konsep Inti & Deep Dive Arsitektur

Terraform adalah Open-Source Infrastructure as Code Software Tool yang dikembangkan oleh HashiCorp. Berbeda dengan alat manajemen konfigurasi seperti Ansible yang bersifat procedural, Terraform menggunakan pendekatan declarative. Anda mendeklarasikan desired state (keadaan akhir yang diinginkan), dan Terraform bertugas menghitung execution plan untuk mencapai state tersebut dari current state saat ini.

Alur Kerja Terraform

  1. Write: Menulis konfigurasi infrastruktur dalam bahasa HashiCorp Configuration Language (HCL).
  2. Plan: Terraform membandingkan kode HCL dengan Remote State yang tersimpan di AWS S3 dan melakukan refresh status dari AWS API untuk membuat execution plan (tindakan create, update, destroy).
  3. Apply: Mengeksekusi plan tersebut ke provider AWS secara aman.
+-------------------------------------------------------------+
|                        Developer                            |
+-------------------------------------------------------------+
       |                                       ^
       v                                       |
+-------------------+               +-------------------------+
|  Terraform Write  | ------------> |    Terraform Plan &     |
|    (HCL Code)     |               |         Apply           |
+-------------------+               +-------------------------+
       |                                       ^
       v                                       |
+-----------------------------------+   +---------------------+
| AWS Provider API Calls            |   | AWS S3 Remote State |
| (VPC, EC2, RDS, ALB, S3, IAM)     |   | + DynamoDB Locking  |
+-----------------------------------+   +---------------------

Komponen inti dalam arsitektur Terraform skala produksi mencakup:

  • Backend: Tempat penyimpanan state file (terraform.tfstate). Di AWS, standar industrinya adalah S3 bucket terenkripsi dengan DynamoDB untuk state locking.
  • Provider: Plugin yang menterjemahkan kode HCL menjadi panggilan API spesifik (dalam hal ini, AWS Provider).
  • Modules: Wadah yang merangkum beberapa resource menjadi satu komponen yang dapat digunakan kembali (reusable), misalnya modul untuk membuat web tier lengkap dengan Nginx, PHP-FPM, dan autoscaling group.

3. Perbandingan Komparatif / Analisis Pendekatan

Untuk memahami mengapa Terraform menjadi pilihan utama dalam manajemen infrastruktur cloud enterprise, mari kita bandingkan dengan pendekatan alternatif.

Parameter Perbandingan Manual AWS Console / CLI AWS CloudFormation Terraform (HashiCorp) Ansible / Chef
Paradigma Imperatif / Manual Deklaratif Deklaratif prosedural / Konfigurasi
Multi-Cloud Support Tidak (Khusus AWS) Tidak (Khusus AWS) Ya (AWS, GCP, Azure, CF) Ya (Multi-platform)
State Management Tidak ada Dikelola AWS (Stack) Remote Backend (S3/DB) Tidak ada bawaan
Modularitas Sangat buruk Terbatas (Nested Stacks) Sangat kuat (Registry) Baik untuk config
Dry Run / Plan Tidak ada Melalui Change Set Sangat Akurat (plan) Terbatas (check)

[!TIP]
Meskipun AWS CloudFormation adalah alat bawaan AWS, Terraform memiliki keunggulan kompetitif pada ekosistem komunitas yang masif, dukungan multi-cloud, dan sintaks HCL yang lebih bersih dibandingkan JSON/YAML yang panjang pada CloudFormation.


4. Prasyarat Sistem & Persiapan Lingkungan

Sebelum mulai menulis kode Terraform untuk infrastruktur web skala produksi, pastikan sistem lokal atau mesin CI/CD Anda memenuhi prasyarat berikut:

  1. Terraform CLI: Versi minimum v1.5.0 atau yang lebih baru.
  2. AWS CLI v2: Terinstal dan terkonfigurasi dengan profil IAM yang memiliki hak akses administratif (AdministratorAccess untuk bootstrap awal, atau least-privilege untuk eksekusi reguler).
  3. Git: Untuk version control.
  4. Kredensial AWS: Simpan kredensial pada ~/.aws/credentials atau gunakan environment variables:
    export AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
    export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
    export AWS_DEFAULT_REGION="us-east-1"
    

Verifikasi instalasi dengan menjalankan perintah:

terraform -version
aws --version

5. Panduan Implementasi Langkah demi Langkah

Bagian ini menyajikan kode implementasi lengkap siap produksi yang mencakup: Pembuatan Remote State Backend (S3 & DynamoDB), Modularisasi Infrastruktur Jaringan (VPC), Security Group, Load Balancer, dan Web Server instance.

Struktur Direktori Proyek

infra-production/
β”œβ”€β”€ modules/
β”‚   β”œβ”€β”€ vpc/
β”‚   β”‚   β”œβ”€β”€ main.tf
β”‚   β”‚   β”œβ”€β”€ variables.tf
β”‚   β”‚   └── outputs.tf
β”‚   └── web_tier/
β”‚       β”œβ”€β”€ main.tf
β”‚       β”œβ”€β”€ variables.tf
β”‚       └── outputs.tf
β”œβ”€β”€ environments/
β”‚   └── production/
β”‚       β”œβ”€β”€ backend.tf
β”‚       β”œβ”€β”€ main.tf
β”‚       β”œβ”€β”€ variables.tf
β”‚       └── outputs.tf
└── bootstrap/
    β”œβ”€β”€ main.tf
    └── outputs.tf

Langkah 1: Bootstrap S3 & DynamoDB untuk State Management

Buat direktori bootstrap/main.tf untuk menyiapkan penyimpanan state file yang aman.

# bootstrap/main.tf
provider "aws" {
  region = "us-east-1"
}

resource "aws_s3_bucket" "terraform_state" {
  bucket        = "prod-app-terraform-state-bucket-unique-name"
  force_destroy = false

  lifecycle {
    prevent_destroy = true
  }
}

resource "aws_s3_bucket_versioning" "enabled" {
  bucket = aws_s3_bucket.terraform_state.id
  versioning_configuration {
    status = "Enabled"
  }
}

resource "aws_s3_bucket_server_side_encryption_by_default" "default" {
  bucket = aws_s3_bucket.terraform_state.id
  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "AES256"
    }
  }
}

resource "aws_dynamodb_table" "terraform_locks" {
  name         = "prod-app-terraform-locks"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }
}

output "s3_bucket_name" {
  value       = aws_s3_bucket.terraform_state.id
  description = "Nama S3 bucket untuk remote state"
}

output "dynamodb_table_name" {
  value       = aws_dynamodb_table.terraform_locks.name
  description = "Nama DynamoDB table untuk state locking"
}

Jalankan perintah bootstrap:

cd bootstrap
terraform init
terraform apply -auto-approve

Langkah 2: Modul VPC (modules/vpc/main.tf)

# modules/vpc/variables.tf
variable "vpc_cidr" {
  type    = string
  default = "10.0.0.0/16"
}

variable "environment" {
  type    = string
  default = "production"
}

# modules/vpc/main.tf
resource "aws_vpc" "main" {
  cidr_block           = var.vpc_cidr
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name        = "${var.environment}-vpc"
    Environment = var.environment
  }
}

data "aws_availability_zones" "available" {
  state = "available"
}

resource "aws_subnet" "public" {
  count                   = 2
  vpc_id                  = aws_vpc.main.id
  cidr_block              = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)
  map_public_ip_on_launch = true
  availability_zone       = data.aws_availability_zones.available.names[count.index]

  tags = {
    Name = "${var.environment}-public-subnet-${count.index + 1}"
  }
}

resource "aws_internet_gateway" "gw" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "${var.environment}-igw"
  }
}

resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.gw.id
  }

  tags = {
    Name = "${var.environment}-public-rt"
  }
}

resource "aws_route_table_association" "public" {
  count          = 2
  subnet_id      = aws_subnet.public[count.index].id
  route_table_id = aws_route_table.public.id
}

# modules/vpc/outputs.tf
output "vpc_id" {
  value = aws_vpc.main.id
}

output "public_subnet_ids" {
  value = aws_subnet.public[*].id
}

Langkah 3: Modul Web Tier / EC2 & Security Group (modules/web_tier/main.tf)

# modules/web_tier/variables.tf
variable "vpc_id" { type = string }
variable "public_subnet_ids" { type = list(string) }
variable "environment" { type = string }

# modules/web_tier/main.tf
resource "aws_security_group" "web_sg" {
  name        = "${var.environment}-web-sg"
  description = "Security group untuk web server Nginx/PHP"
  vpc_id      = var.vpc_id

  ingress {
    description = "Allow HTTP dari internet"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    description = "Allow HTTPS dari internet"
    from_port   = 443
    to_port     = 443
    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"]
  }

  tags = {
    Name = "${var.environment}-web-sg"
  }
}

data "aws_ami" "ubuntu" {
  most_recent = true
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
  }
  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
  owners = ["099720109477"]
}

resource "aws_instance" "web_server" {
  ami                    = data.aws_ami.ubuntu.id
  instance_type          = "t3.medium"
  subnet_id              = var.public_subnet_ids[0]
  vpc_security_group_ids = [aws_security_group.web_sg.id]

  user_data = <<-EOF
              #!/bin/bash
              apt-get update -y
              apt-get install -y nginx php-fpm mysql-client redis-server
              systemctl start nginx
              systemctl enable nginx
              echo "<h1>Enterprise Production Web Server - Terraform Powered</h1>" > /var/www/html/index.nginx-debian.html
              EOF

  tags = {
    Name = "${var.environment}-web-node-1"
  }
}

# modules/web_tier/outputs.tf
output "web_instance_ip" {
  value = aws_instance.web_server.public_ip
}

Langkah 4: Konfigurasi Environment Production (environments/production/)

# environments/production/backend.tf
terraform {
  required_version = ">= 1.5.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  backend "s3" {
    bucket         = "prod-app-terraform-state-bucket-unique-name"
    key            = "production/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "prod-app-terraform-locks"
    encrypt        = true
  }
}

provider "aws" {
  region = "us-east-1"
}

# environments/production/main.tf
module "vpc" {
  source      = "../../modules/vpc"
  vpc_cidr    = "10.100.0.0/16"
  environment = "production"
}

module "web_tier" {
  source            = "../../modules/web_tier"
  vpc_id            = module.vpc.vpc_id
  public_subnet_ids = module.vpc.public_subnet_ids
  environment       = "production"
}

# environments/production/outputs.tf
output "production_web_ip" {
  value       = module.web_tier.web_instance_ip
  description = "Public IP dari web server produksi"
}

Jalankan inisialisasi dan deploy environment production:

cd environments/production
terraform init
terraform plan -out=tfplan
terraform apply tfplan

6. Bedah Kode & Penjelasan Detail Baris Kunci

  • Backend S3 & DynamoDB Locking (backend.tf): Baris dynamodb_table krusial untuk mencegah race condition. Jika dua engineer menjalankan terraform apply secara bersamaan, DynamoDB akan mengunci state file, menghindari korupsi data infrastruktur.
  • lifecycle { prevent_destroy = true }: Parameter pengaman tingkat lanjut pada resource S3 bucket state. Ini memastikan bahwa state file utama tidak dapat terhapus secara tidak sengaja saat perintah terraform destroy global dieksekusi.
  • cidrsubnet(...) function: Digunakan secara dinamis untuk memecah CIDR blok VPC utama (10.100.0.0/16) menjadi subnet-subnet yang lebih kecil dengan prefiks /24 secara otomatis berdasarkan count.index.
  • user_data bootstrapping: Skrip provisioning inline yang menginstal Nginx, PHP-FPM, MySQL client, dan Redis sesaat setelah EC2 instance menyala. Untuk produksi yang lebih kompleks, skrip ini biasanya digantikan oleh Ansible playbook atau AMI kustom yang dibangun dengan Packer.

7. Skenario Produksi & Studi Kasus Dunia Nyata

Pada sistem skala enterprise dengan trafik tinggi (contoh: E-commerce Flash Sale atau News Portal dengan 100.00 ΰ¦šΰ§‡ΰ¦―ΰ¦Όΰ§‡ concurrent users), instance tunggal akan kolaps. Arsitektur produksi harus bertransformasi menggunakan Auto Scaling Group (ASG), Application Load Balancer (ALB), dan Amazon RDS (Multi-AZ MySQL).

Berikut snippet konfigurasi tambahan untuk mengarahkan arsitektur ke High Availability:

resource "aws_lb" "app_alb" {
  name               = "prod-web-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.web_sg.id]
  subnets            = var.public_subnet_ids
}

resource "aws_lb_target_group" "app_tg" {
  name     = "prod-web-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = var.vpc_id

  health_check {
    path                = "/index.nginx-debian.html"
    healthy_threshold   = 2
    unhealthy_threshold = 10
  }
}

resource "aws_lb_listener" "http" {
  load_balancer_arn = aws_lb.app_alb.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.app_tg.arn
  }
}

8. Common Pitfalls, Anti-Patterns & Solusi

  1. Hardcoding Kredensial dan Secret di Kode HCL
    • Anti-Pattern: Menulis password database atau API key secara langsung di file main.tf atau variables.tf.
    • Solusi: Selalu gunakan AWS Systems Manager Parameter Store, AWS Secrets Manager, atau environment variables (TF_VAR_variable_name).
  2. Mengabaikan Drift Detection
    • Anti-Pattern: Mengubah konfigurasi firewall atau instance langsung melalui AWS Console tanpa memperbarui kode Terraform.
    • Solusi: Jadwalkan perintah terraform plan secara berkala (misal via cronjob CI/CD) untuk mendeteksi configuration drift.
  3. Monolitik State File
    • Anti-Pattern: Menggabungkan seluruh infrastruktur (VPC, Database, Kubernetes, IAM, DNS Cloudflare) ke dalam satu state file besar.
    • Solusi: Terapkan Terraform Workspaces atau pisahkan state berdasarkan layer menggunakan direktori terisolasi (Networking Layer, Database Layer, Application Layer).

9. Benchmark, Metrik Kinerja & Tuning Performa

Untuk memastikan infrastruktur web yang di-provision oleh Terraform mampu menangani beban operasional nyata, lakukan pengujian beban menggunakan k6 atau wrk terhadap Application Load Balancer.

Contoh skrip pengujian k6 (load-test.js):

import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  stages: [
    { duration: '1m', target: 50 },  // Ramp-up ke 50 users
    { duration: '3m', target: 200 }, // Pertahankan 200 concurrent users
    { duration: '1m', target: 0 },   // Ramp-down
  ],
};

export default function () {
  const res = http.get('http://prod-web-alb-123456789.us-east-1.elb.amazonaws.com');
  check(res, {
    'status is 200': (r) => r.status === 200,
    'response time < 200ms': (r) => r.timings.duration < 200,
  });
  sleep(1);
}

[!WARNING] Pastikan untuk melakukan load testing hanya pada lingkungan staging atau production yang telah dikoordinasikan dengan tim keamanan, guna menghindari pemicu aturan AWS WAF atau Shield terhadap dugaan serangan DDoS.


10. Checklist Penerapan Produksi & Kesimpulan

Sebelum meluncurkan infrastruktur Terraform ke lingkungan produksi, pastikan Anda telah memverifikasi checklist berikut:

  • Remote State S3 terenkripsi dengan AES256 dan versioning aktif.
  • DynamoDB State Locking diaktifkan untuk menghindari konkurensi tulis.
  • Tidak ada hardcode secret; seluruh sensitif data menggunakan AWS Secrets Manager / Parameter Store.
  • Security Group menerapkan prinsip Least Privilege (hanya port 80/443 terbuka ke publik, port SSH dibatasi ke bastion host / VPN).
  • Modul telah diuji menggunakan terraform validate dan tflint untuk analisis statis.
  • Backup otomatis database dan snapshot EBS telah dikonfigurasi melalui Terraform.

Dengan mengikuti panduan komprehensif ini, Anda kini memiliki fondasi rekrutmen infrastruktur cloud enterprise yang resilien, terstandarisasi, aman, dan siap diskalakan sesuai pertumbuhan bisnis web modern.

🏷️ Tags: #Nginx #High Concurrency #Performance #Sysadmin #Web Server