Automasi Infrastruktur Enterprise Menggunakan Terraform dan Ansible di AWS
Automasi Infrastruktur Enterprise Menggunakan Terraform dan Ansible di AWS
1. Konteks Industri & Analisis Akar Masalah
Dalam lanskap enterprise modern, kecepatan rilis fitur dan stabilitas sistem adalah dua pilar penentu daya saing bisnis. Namun, banyak organisasi masih terjebak dalam model operasional lama yang mengandalkan manajemen infrastruktur manual (manual provisioning). Pendekatan ini tidak hanya lambat, tetapi juga membuka celah lebar terhadap inkonsistensi lingkungan (environment drift), kesalahan manusia (human error), dan kerentanan keamanan yang sulit dilacak.
Di dunia nyata, infrastruktur web enterprise tidak berdiri sendiri. Ia adalah ekosistem kompleks yang melibatkan orkestrasi Virtual Private Cloud (VPC), klaster Kubernetes (EKS), layanan basis data terdistribusi (MySQL/MariaDB), sistem caching berperforma tinggi (Redis), mekanisme queue & scheduler (Supervisor, Cron), hingga lapisan pengamanan tepi seperti Cloudflare WAF, SSL/TLS, dan manajemen DNS tingkat lanjut. Jika proses provisioning dan konfigurasi layanan-layanan ini dilakukan melalui konsol AWS atau SSH manual, proses disaster recovery dapat memakan waktu berhari-hari.
Perbandingan Kondisi: Sebelum vs Sesudah Automasi
| Parameter | Sebelum Automasi (Manual / Ad-hoc) | Sesudah Automasi (Terraform + Ansible) | Dampak Bisnis |
|---|---|---|---|
| Waktu Provisioning | 3 - 5 Hari Kerja | 10 - 15 Menit | Time-to-market meningkat drastis |
| Inkonsistensi Environment | Tinggi (dev vs staging vs prod berbeda) | Nol (Infrastruktur sebagai Kode) | Mengurangi bug yang hanya muncul di prod |
| Auditabilitas | Lemah (bergantung pada memori tim) | Kuat (Git History sebagai source of truth) | Kepatuhan (Compliance) mudah dicapai |
| Disaster Recovery | Berjam-jam hingga berhari-hari | Hitungan menit (Infrastructure Recreation) | High Availability dan Business Continuity |
Dengan memadukan Terraform untuk orkestrasi infrastruktur imajinatif (IaaS) dan Ansible untuk manajemen konfigurasi sistem operasi serta aplikasi (Configuration Management), organisasi dapat mencapai siklus hidup infrastruktur yang sepenuhnya deklaratif, dapat diulang (repeatable), dan aman secara default.
2. Konsep Inti & Deep Dive Arsitektur
Arsitektur enterprise modern menuntut pemisahan tugas yang jelas antara pembuatan fondasi infrastruktur dan konfigurasi di dalam instans. Terraform bertindak sebagai declarative provisioner yang berinteraksi langsung dengan AWS API untuk membangun sumber daya fisik, sementara Ansible mengambil alih setelah instans siap untuk menginstal paket, mengatur konfigurasi Nginx/PHP-FPM, mengamankan daemon SSH, dan menjalankan layanan latar belakang.
Berikut adalah representasi visual alur eksekusi dari kode hingga infrastruktur hidup:
+--------------------------------------------------------------------------+
| Developer / Git |
+--------------------------------------------------------------------------+
|
v
+--------------------------------------------------------------------------+
| Terraform (Declarative IaaS) |
| - AWS VPC (Public/Private Subnets, NAT Gateway, Internet Gateway) |
| - AWS EKS Cluster (Control Plane, Worker Nodes, IAM Roles) |
| - RDS MySQL & ElastiCache Redis |
+--------------------------------------------------------------------------+
|
v
+--------------------------------------------------------------------------+
| Ansible (Configuration Management) |
| - OS Hardening & Fail2ban Setup |
| - Web Server (Nginx / Caddy) & PHP-FPM Pool Configuration |
| - Supervisor Queue Workers & Cron Jobs |
+--------------------------------------------------------------------------+
|
v
+--------------------------------------------------------------------------+
| Production Web Ecosystem Ready |
+--------------------------------------------------------------------------+
Alur Data & Eksekusi Under the Hood
- Inisialisasi Terraform: Terraform membaca file
.tf, melakukan parsing grafik ketergantungan (dependency graph), dan mencocokkan status lokal/remote dengan state aktual di AWS. - Eksekusi AWS API: Terraform memicu pembuatan VPC, subnet multi-AZ, route tables, internet gateway, NAT gateway, dan meluncurkan klaster EKS.
- Dinamis Ekstraksi IP/DNS: Output Terraform (seperti IP instans atau endpoint RDS) diekspor secara otomatis atau disimpan ke dalam file inventaris Ansible.
- Eksekusi Playbook Ansible: Ansible melakukan koneksi SSH berbasis kunci ke instans target, mengeksekusi peran (roles) secara berurutan, menerapkan hardening keamanan, dan menyalakan service web server.
3. Perbandingan Komparatif / Analisis Pendekatan
Dalam membangun pipeline otomatisasi, arsitek sering dihadapkan pada pilihan alat. Berikut adalah analisis mendalam mengenai trade-off pendekatan yang digunakan:
| Aspek Penilaian | Terraform | Ansible | CloudFormation / AWS SSM |
|---|---|---|---|
| Paradigma | Deklaratif (IaaS) | Prosedural/Deklaratif (Config Mgmt) | Deklaratif (Native AWS) |
| Cakupan Multi-Cloud | Sangat Luas (AWS, GCP, Azure, Cloudflare) | Luas (OS, Network Devices, Cloud) | Terbatas hanya pada ekosistem AWS |
| State Management | Menggunakan State File (Local/Remote S3) | Stateless (Berbasis SSH & Inventaris) | Dikelola penuh oleh AWS Control Plane |
| Konsumsi CPU & RAM | Ringan (Go Binary) | Sangat Ringan (Python/SSH Agentless) | Dikelola oleh AWS Backend |
| Kurva Pembelajaran | Menengah (HCL syntax) | Rendah (YAML syntax) | Menengah-Tinggi (YAML/JSON Verbose) |
[!TIP] Gunakan Terraform untuk membuat wadah dan infrastruktur dasarnya (infrastructure provisioning), lalu gunakan Ansible untuk mengisi isi dalam instans tersebut (configuration management). Jangan mencoba menggunakan Terraform untuk manajemen file konfigurasi aplikasi yang kompleks, karena hal tersebut adalah ranah utama Ansible.
4. Prasyarat Sistem & Persiapan Lingkungan
Sebelum melangkah ke implementasi kode, pastikan workstation atau CI/CD runner Anda memiliki spesifikasi dan perangkat lunak berikut terinstal dengan benar:
Spesifikasi & Dependensi
- OS: Linux (Ubuntu 22.04 LTS / Amazon Linux 2023) atau macOS Sonoma/Ventura.
- Terraform: Versi
>= 1.5.0 - Ansible: Versi
>= 2.15.0 - AWS CLI: Versi
2.xdengan kredensial IAM yang memiliki hak akses administrator penuh (AdministratorAccess atau PowerUserAccess). - Git: Untuk manajemen versi modul.
Verifikasi instalasi dengan menjalankan perintah berikut di terminal:
terraform version
ansible --version
aws --version
Pastikan variabel lingkungan AWS telah dikonfigurasi dengan benar:
export AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
export AWS_DEFAULT_REGION="ap-southeast-1"
5. Panduan Implementasi Langkah demi Langkah
Bagian ini menyajikan kode implementasi lengkap siap produksi. Kita akan memecahnya menjadi modul Terraform untuk VPC dan EKS, manajemen state menggunakan S3 + DynamoDB, serta konfigurasi server menggunakan Ansible.
5.1 Desain Modul Terraform untuk VPC
Buat direktori proyek dengan struktur berikut:
infra-enterprise/
├── modules/
│ ├── vpc/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── eks/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── backend.tf
├── main.tf
├── variables.tf
└── outputs.tf
Isi file modules/vpc/main.tf:
variable "vpc_cidr" {
type = string
default = "10.0.0.0/16"
}
variable "environment" {
type = string
default = "production"
}
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
}
}
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.vpc_cidr, 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_subnet" "private" {
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-subnet-${count.index + 1}
}
}
data "aws_availability_zones" "available" {
state = "available"
}
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${var.environment}-igw"
}
}
resource "aws_eip" "nat" {
domain = "vpc"
}
resource "aws_nat_gateway" "nat" {
allocation_id = aws_eip.nat.id
subnet_id = aws_subnet.public[0].id
tags = {
Name = "${var.environment}-nat-gw"
}
}
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" "private" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.nat.id
}
tags = {
Name = "${var.environment}-private-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
}
resource "aws_route_table_association" "private" {
count = 2
subnet_id = aws_subnet.private[count.index].id
route_table_id = aws_route_table.private.id
}
output "vpc_id" {
value = aws_vpc.main.id
}
output "private_subnets" {
value = aws_subnet.private[*].id
}
output "public_subnets" {
value = aws_subnet.public[*].id
}
5.2 Desain Modul Terraform untuk EKS
Isi file modules/eks/main.tf:
variable "cluster_name" {
type = string
default = "enterprise-eks-cluster"
}
variable "subnet_ids" {
type = list(string)
}
resource "aws_iam_role" "eks_cluster" {
name = "${var.cluster_name}-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "eks.amazonaws.com"
}
}]
})
}
resource "aws_iam_role_policy_attachment" "eks_cluster_policy" {
role = aws_iam_role.eks_cluster.name
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
}
resource "aws_eks_cluster" "main" {
name = var.cluster_name
role_arn = aws_iam_role.eks_cluster.arn
vpc_config {
subnet_ids = var.subnet_ids
}
depends_on = [aws_iam_role_policy_attachment.eks_cluster_policy]
}
output "cluster_endpoint" {
value = aws_eks_cluster.main.endpoint
}
output "cluster_name" {
value = aws_eks_cluster.main.name
}
5.3 Manajemen State Berkelanjutan
Isi file backend.tf untuk menyimpan state di AWS S3 dengan penguncian DynamoDB guna mencegah konflik konkurensi:
terraform {
backend "s3" {
bucket = "enterprise-terraform-state-bucket-xyz"
key = "production/terraform.tfstate"
region = "ap-southeast-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
5.4 Konfigurasi OS dan Service Provisioning dengan Ansible
Buat struktur direktori Ansible:
ansible/
├── inventory/
│ └── hosts.ini
├── roles/
│ └── webserver/
│ ├── tasks/
│ │ └── main.yml
│ └── templates/
│ └── nginx.conf.j2
└── playbook.yml
Isi file ansible/inventory/hosts.ini:
[webservers]
server-prod-01 ansible_host=54.169.10.20 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/prod-key.pem
[webservers:vars]
ansible_python_interpreter=/usr/bin/python3
Isi file ansible/roles/webserver/tasks/main.yml:
---
- name: Update apt cache and install Nginx & PHP-FPM
apt:
name:
- nginx
- php8.2-fpm
- php8.2-mysql
- redis
- fail2ban
state: present
update_cache: yes
- name: Configure Nginx virtual host from template
template:
src: nginx.conf.j2
dest: /etc/nginx/sites-available/default
owner: root
group: root
mode: '0644'
notify: Restart Nginx
- name: Ensure Fail2ban service is running and enabled
service:
name: fail2ban
state: started
enabled: yes
- name: Ensure Nginx service is running and enabled
service:
name: nginx
state: started
enabled: yes
- name: Ensure PHP-FPM service is running and enabled
service:
name: php8.2-fpm
state: started
enabled: yes
Handler untuk Ansible di ansible/roles/webserver/handlers/main.yml:
---
- name: Restart Nginx
service:
name: nginx
state: restarted
File ansible/playbook.yml:
---
- hosts: webservers
become: yes
roles:
- webserver
Jalankan Ansible dengan perintah:
ansible-playbook -i ansible/inventory/hosts.ini ansible/playbook.yml
6. Bedah Kode & Penjelasan Detail Baris Kunci
cidrsubnet(var.vpc_cidr, 8, count.index): Fungsi internal Terraform ini memecah blok CIDR utama (misal/16) menjadi sub-blok (/24) secara dinamis berdasarkan indeks iterasi. Ini mencegah hardcode IP dan memastikan kalkulasi jaringan matematis tanpa tumpang tindih (overlap).backend "s3": Konfigurasi kunci enterprise. Menyimpan state di local rentan terhadap korupsi file saat dikerjakan oleh tim. S3 mengenkripsi state secara at-rest, sementara DynamoDB memberikan mekanisme state locking atomik.become: yespada Ansible: Menjalankan tugas-tugas konfigurasi di bawah hak aksessudo(root), mutlak diperlukan untuk instalasi paket OS, modifikasi konfigurasi Nginx di/etc/nginx, dan pengelolaan systemd services.
7. Skenario Produksi & Studi Kasus Dunia Nyata
Dalam menghadapi flash sale atau lonjakan trafik e-commerce tiba-tiba (misal 50.000 requests per second), arsitektur yang dibangun harus siap melakukan auto-scaling.
- Infrastruktur Dasar: Terraform menyediakan Auto Scaling Group (ASG) di belakang Application Load Balancer (ALB) dengan zona ketersediaan ganda (Multi-AZ).
- Manajemen Konfigurasi Cepat: Saat instans baru diputar (spawned) oleh ASG, skrip cloud-init memanggil Ansible pull mode atau menarik konfigurasi yang telah di-bake ke dalam Amazon Machine Image (AMI) menggunakan Packer.
- Kinerja Web & Database: Nginx dikonfigurasi dengan worker_processes auto dan keepalive_timeout 65, sementara Redis bertindak sebagai session store dan query cache untuk mengurangi beban basis data MySQL Aurora.
8. Common Pitfalls, Anti-Patterns & Solusi
[!WARNING] Kesalahan Fatal #1: Menyimpan AWS Secret Access Key atau SSH Private Key secara plainteks di dalam repositori Git publik maupun privat. Solusi: Gunakan AWS Secrets Manager, HashiCorp Vault, atau variabel lingkungan terenkripsi. Manfaatkan file
.gitignoresecara ketat.
[!WARNING] Kesalahan Fatal #2: Menghapus atau mengubah struktur resource block di Terraform tanpa melakukan migrasi state (
terraform state mv), yang menyebabkan sumber daya produksi terhapus tidak sengaja (destroy/recreate). Solusi: Selalu jalankanterraform plandan periksa bendanya dengan teliti. Gunakan lifecycle { prevent_destroy = true } pada database kritis.
9. Benchmark, Metrik Kinerja & Tuning Performa
Untuk memverifikasi kesiapan performa server web yang dikonfigurasi melalui Ansible, jalankan pengujian beban menggunakan k6 atau wrk:
wrk -t12 -c400 -d30s http://enterprise-alb-123456789.ap-southeast-1.elb.amazonaws.com/
Parameter Tuning Kernel Linux (/etc/sysctl.conf):
Terapkan parameter berikut melalui peran Ansible untuk menangani koneksi TCP konkurensi tinggi:
# Meningkatkan batas maksimal file descriptor
fs.file-max = 2097152
# Optimasi ukuran buffer TCP socket
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.ip_local_port_range = 1024 65535
Terapkan perubahan dengan perintah sysctl -p.
10. Checklist Penerapan Produksi & Kesimpulan
Sebelum merilis infrastruktur ini ke lingkungan live, pastikan Anda telah melewati checklist berikut:
- State Terraform diamankan di S3 dengan enkripsi KMS dan dikunci via DynamoDB.
- Seluruh port keamanan Security Groups AWS dibatasi secara ketat (prinsip least privilege).
- Ansible Playbook telah diuji pada staging environment tanpa error (Idempotensi terbukti).
- Fail2ban dan pembaruan keamanan otomatis OS telah aktif.
- Pemantauan (Monitoring) dan Logging (CloudWatch / Prometheus) telah terpasang pada klaster EKS dan instans.
Dengan memadukan Terraform dan Ansible secara disiplin, tim infrastruktur enterprise Anda memiliki fondasi yang tangguh, dapat diskalakan secara masif, dan tahan terhadap bencana operasional.