Arsitektur Infrastructure as Code (IaC) Skala Enterprise dengan Terraform dan AWS
Arsitektur Infrastructure as Code (IaC) Skala Enterprise dengan Terraform dan AWS
1. Konteks Industri & Analisis Akar Masalah
Dalam lanskap pengembangan aplikasi enterprise modern, skalabilitas, keamanan, dan keandalan sistem bukan lagi sekadar nilai tambah, melainkan fondasi bisnis yang mutlak. Di era di mana platform web menangani jutaan permintaan per detik (high concurrency), mengandalkan manajemen infrastruktur manual melalui AWS Console atau skrip bash kustom adalah sebuah bom waktu.
Masalah klasik yang sering dihadapi oleh tim DevOps dan Infrastructure Architect meliputi:
- Configuration Drift: Perbedaan status infrastruktur aktual di production dengan dokumentasi atau spesifikasi awal akibat perubahan manual darurat (hotfix).
- Human Error: Kesalahan manusia saat mengonfigurasi Security Groups, subnet VPC, atau pengaturan IAM role yang berdampak pada celah keamanan fatal.
- Lack of Reproducibility: Kesulitan mereplikasi environment (Staging, UAT, Production) dengan presisi 100%, menyebabkan bug yang hanya muncul di production.
- Vendor Lock-in & Maintenance Overhead: Kesulitan melacak dependensi sumber daya cloud seiring bertambahnya kompleksitas sistem.
Sebelum vs Sesudah Penerapan Terraform IaC
| Parameter | Sebelum (Manual / Skrip Ad-hoc) | Sesudah (Declarative IaC dengan Terraform) | Dampak Bisnis |
|---|---|---|---|
| Waktu Provisioning | Berhari-hari hingga berminggu-minggu | Hitungan menit (10 - 15 menit) | Time-to-market jauh lebih cepat |
| Auditabilitas | Tidak ada jejak historis yang jelas | Version-controlled di Git (Pull Request & Code Review) | Kepatuhan (Compliance) SOC2/ISO27001 terpenuhi |
| Recovery Time (DR) | Lambat, rentan salah langkah saat darurat | Otomatis melalui destroy/apply command | Downtime minimal, RTO & RPO tercapai |
| Konsistensi Environment | Tinggi potensi deviasi antar environment | Identik secara mutlak (Dev, Stage, Prod) | Menurunkan insiden bug akibat environment mismatch |
2. Konsep Inti & Deep Dive Arsitektur
Terraform menggunakan paradigma declarative infrastructure. Anda mendefinisikan desired state (keadaan yang diinginkan) dari infrastruktur, dan Terraform bertanggung jawab untuk menghitung diff (perbedaan) antara desired state dengan current state yang tercatat di state file, lalu mengeksekusi rencana (execution plan) untuk mencapai state target.
Alur Eksekusi Terraform dan Interaksi AWS API
+-------------------------------------------------------------------------+
| Developer / CI/CD Pipeline |
| (terraform apply / terraform plan) |
+-------------------------------------------------------------------------+
|
v
+-------------------------------------------------------------------------+
| Terraform Core Engine |
| - Parsing HCL (HashiCorp Configuration Language) |
| - Dependency Graph Generation |
+-------------------------------------------------------------------------+
| |
v v
+---------------------------------+ +-----------------------------------+
| Remote State Backend (AWS S3) | | AWS Provider Plugin |
| - tfstate file Locking (DynamoDB)| | - Translates to AWS API Requests |
+---------------------------------+ +-----------------------------------+
|
v
+-----------------------------------+
| AWS Cloud |
| (VPC, EC2, RDS, ALB, S3, ElastiCache)|
+-----------------------------------+
Komponen inti dalam ekosistem Terraform mencakup:
- Providers: Plugin yang memungkinkan Terraform berinteraksi dengan API penyedia cloud (AWS, Cloudflare, GitHub, dll).
- Resources: Blok fundamental yang merepresentasikan komponen infrastruktur (misalnya
aws_instance,aws_vpc). - Modules: Wadah untuk beberapa resource yang dikelompokkan agar dapat digunakan kembali (reusable).
- State File (
terraform.tfstate): File JSON yang memetakan sumber daya real-world ke konfigurasi Terraform Anda.
3. Perbandingan Komparatif / Analisis Pendekatan
Dalam membangun arsitektur IaC di AWS, terdapat beberapa pendekatan tool selain Terraform. Berikut adalah analisis komparatif mendalam:
| Fitur / Parameter | Terraform (HashiCorp / OpenTofu) | AWS CloudFormation | AWS CDK (Cloud Development Kit) |
|---|---|---|---|
| Bahasa | HCL (Declarative) | YAML / JSON | TypeScript, Python, Java, C# |
| Multi-Cloud Support | Ya (AWS, GCP, Azure, Cloudflare, dll) | Tidak (Khusus AWS) | Tidak (Khusus AWS & K8s via cdk8s) |
| State Management | Remote Backend (S3 + DynamoDB) | Dikelola penuh oleh AWS Stack | Dikelola penuh oleh AWS CloudFormation |
| Kurva Belajar | Sedang (HCL sangat intuitif) | Mudah/Sedang (Struktur YAML besar) | Tinggi (Butuh pemahaman OOP & CloudFormation) |
| Ekosistem Modul | Sangat luas (Terraform Registry) | Terbatas pada AWS Constructs | Luas (AWS Constructs Library) |
[!TIP] Gunakan Terraform ketika Anda membutuhkan fleksibilitas multi-cloud (misalnya memadukan AWS dengan Cloudflare untuk CDN/WAF dan DNS management) serta kontrol penuh atas siklus hidup state file.
4. Prasyarat Sistem & Persiapan Lingkungan
Sebelum menyelam ke dalam kode implementasi, pastikan environment lokal atau runner CI/CD Anda memiliki prasyarat berikut:
- Terraform CLI (Versi >= 1.5.0)
- AWS CLI v2 terinstal dan terkonfigurasi dengan credential yang memiliki hak akses administrator (atau policy minimal seperti AdministratorAccess untuk lab awal).
- Git untuk version control.
Verifikasi instalasi:
terraform version
aws --version
Konfigurasi kredensial AWS:
aws configure
# Masukkan AWS Access Key ID, Secret Access Key, Region (cth: ap-southeast-1), dan format output (json)
5. Panduan Implementasi Langkah demi Langkah
Kita akan membangun arsitektur web enterprise 3-tier di AWS yang mencakup:
- Custom VPC (Multi-AZ dengan Public, Private App, dan Database Subnets).
- Application Load Balancer (ALB) dengan SSL Termination.
- Auto Scaling Group (ASG) untuk Web/Backend Server (Nginx + PHP-FPM / Node.js).
- Amazon Aurora MySQL Database berkecepatan tinggi di Private Subnet.
- Amazon ElastiCache (Redis) untuk caching session dan query.
- Amazon S3 bucket untuk asset storage.
Struktur Direktori Proyek
infra-enterprise/
├── backend.tf
├── provider.tf
├── variables.tf
├── outputs.tf
├── main.tf
└── modules/
├── vpc/
├── alb/
├── database/
└── compute/
1. File backend.tf (Remote State & Locking)
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "company-terraform-state-prod-xyz"
key = "enterprise-web/terraform.tfstate"
region = "ap-southeast-1"
dynamodb_table = "company-terraform-locks"
encrypt = true
}
}
2. File provider.tf
provider "aws" {
region = var.aws_region
default_tags {
tags = {
Environment = var.environment
Project = "EnterpriseWebPlatform"
ManagedBy = "Terraform"
}
}
}
3. File variables.tf
variable "aws_region" {
type = string
default = "ap-southeast-1"
}
variable "environment" {
type = string
default = "production"
}
variable "vpc_cidr" {
type = string
default = "10.100.0.0/16"
}
variable "db_password" {
type = string
sensitive = true
}
4. Modul VPC (modules/vpc/main.tf)
variable "vpc_cidr" { type = string }
variable "environment" { type = string }
data "aws_availability_zones" "available" {
state = "available"
}
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${var.environment}-vpc"
}
}
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.vpc_cidr, 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Name = "${var.environment}-public-subnet-${count.index + 1}"
}
}
resource "aws_subnet" "private_app" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.vpc_cidr, 8, count.index + 10)
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = {
Name = "${var.environment}-private-app-subnet-${count.index + 1}"
}
}
resource "aws_subnet" "private_db" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.vpc_cidr, 8, count.index + 20)
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = {
Name = "${var.environment}-private-db-subnet-${count.index + 1}"
}
}
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.main.id
tags = { Name = "${var.environment}-igw\