Implementasi Infrastruktur sebagai Kode (IaC) Menggunakan Terraform dan Ansible
Implementasi Infrastruktur sebagai Kode (IaC) Menggunakan Terraform dan Ansible
1. Konteks Industri & Analisis Akar Masalah
Di era komputasi awan modern, pengelolaan infrastruktur secara manual melalui konsol web (klik sana-sini atau ClickOps) adalah sebuah anti-pola (anti-pattern) yang mengundang bencana operasional. Ketika sebuah platform web enterprise harus melayani jutaan pengguna dengan arsitektur yang mencakup load balancer, klaster web server (Nginx/PHP-FPM/Node.js), database terdistribusi (MySQL/MariaDB), sistem caching (Redis), penyimpanan objek (S3/MinIO), hingga lapisan keamanan (WAF, Fail2ban, Let's Encrypt SSL), konfigurasi manual menjadi mustahil untuk direplikasi secara konsisten.
Akar masalah dari infrastruktur manual meliputi Configuration Drift (perbedaan konfigurasi antar server akibat perubahan manual yang tidak tercatat), lambatnya waktu pemulihan saat bencana (Disaster Recovery), dan tingginya risiko human error.
Sebelum penerapan Infrastructure as Code (IaC) dan Configuration Management otomatis:
- Waktu Provisioning: Membutuhkan waktu berhari-hari bahkan berminggu-minggu untuk menyiapkan lingkungan staging dan production.
- Konsistensi: Server staging sering kali berbeda dengan production, menyebabkan bug "di lokal jalan, di production error".
- Auditabilitas: Tidak ada rekam jejak (version control) siapa yang mengubah konfigurasi sistem.
Sesudah penerapan Terraform dan Ansible:
- Waktu Provisioning: Seluruh infrastruktur dan konfigurasi OS/aplikasi dapat di-spin up dalam hitungan menit secara otomatis.
- Konsistensi: Prinsip Immutable Infrastructure memastikan setiap server identik.
- Auditabilitas: Seluruh perubahan infrastruktur tercatat dalam Git (GitOps).
2. Konsep Inti & Deep Dive Arsitektur
Pendekatan modern memisahkan tanggung jawab secara tegas:
- Terraform (Declarative Provisioning): Bertugas membuat dan mengelola sumber daya infrastruktur cloud (VPC, Subnet, EC2/Compute, Security Groups, S3 Buckets, DNS Records di Cloudflare/Route53).
- Ansible (Imperative/Declarative Configuration Management): Bertugas masuk ke dalam server yang telah di-provision oleh Terraform, melakukan instalasi paket (Nginx, PHP, Node.js, Redis, Postfix), mengatur konfigurasi file, menjalankan service, serta memastikan keamanan dasar (Fail2ban, UFW).
[Developer / CI Pipeline]
|
+---> (git push) ---> [GitHub Repository]
|
+---> 1. terraform apply ---> [AWS Cloud (VPC, EC2, S3, RDS)]
|
+---> 2. ansible-playbook ---> [OS & Web Stack (Nginx, PHP-FPM, Redis, PostgreSQL)]
Alur eksekusi dimulai dari definisi kode HCL (HashiCorp Configuration Language) di Terraform, menghasilkan state lokal/remote, mengekspos IP server ke Ansible Inventory secara dinamis, dan diakhiri dengan eksekusi playbook Ansible melalui SSH.
3. Perbandingan Komparatif / Analisis Pendekatan
| Parameter | Terraform Saja (Cloud-init) | Ansible Saja | Kombinasi Terraform + Ansible |
|---|---|---|---|
| Fokus Utama | Infrastruktur Cloud (IaaS/PaaS) | Manajemen Konfigurasi OS & Aplikasi | Saling melengkapi (End-to-End Automation) |
| Manajemen State | Sangat Kuat (Terraform State) | Tidak ada state, berbasis idempotency | Ideal: Terraform untuk Infra, Ansible untuk App |
| Kompleksitas Skrip | Tinggi jika dipakai untuk instalasi paket kompleks | Rendah untuk app, tinggi untuk buat VPC/Subnet | Menjaga kode tetap bersih dan modular |
| Kecepatan Eksekusi | Cepat (Parallel API calls) | Cepat (SSH parallel execution) | Optimal jika diintegrasikan dengan benar |
| Penggunaan Resource | API Cloud Provider | CPU/RAM lokal/Bastion saat eksekusi SSH | Distribusi resource seimbang |
4. Prasyarat Sistem & Persiapan Lingkungan
Sebelum memulai implementasi, pastikan tools berikut terinstal di mesin lokal atau CI/CD runner Anda:
- Terraform: Versi >= 1.5.0
- Ansible: Versi >= 2.15
- AWS CLI: Terkonfigurasi dengan credential yang memiliki hak akses administrator/IAM yang cukup.
- SSH Key Pair:
id_rsadanid_rsa.pubuntuk akses ke instance.
Struktur direktori proyek yang akan kita bangun:
infra-enterprise/
├── terraform/
│ ├── environments/
│ │ ├── staging/
│ │ │ ├── main.tf
│ │ │ ├── variables.tf
│ │ │ └── outputs.tf
│ │ └── production/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── modules/
│ │ ├── vpc/
│ │ └── ec2/
│ └── backend.tf
└── ansible/
├── inventory/
│ ├── staging
│ └── production
├── playbooks/
│ └── webserver.yml
└── roles/
├── common/
├── nginx/
├── php-fpm/
└── redis/
5. Panduan Implementasi Langkah demi Langkah
Modul Terraform: EC2 Instance (terraform/modules/ec2/main.tf)
variable "ami_id" {
type = string
description = "AMI ID for Ubuntu 22.04 LTS"
}
variable "instance_type" {
type = string
default = "t3.medium"
}
variable "subnet_id" {
type = string
}
variable "security_group_ids" {
type = list(string)
}
variable "environment" {
type = string
}
resource "aws_instance" "web" {
ami = var.ami_id
instance_type = var.instance_type
subnet_id = var.subnet_id
vpc_security_group_ids = var.security_group_ids
key_name = "infra-key-${var.environment}"
root_block_device {
volume_size = 40
volume_type = "gp3"
delete_on_termination = false
}
tags = {
Name = "web-server-${var.environment}"
Environment = var.environment
ManagedBy = "Terraform"
}
}
output "public_ip" {
value = aws_instance.web.public_ip
}
Konfigurasi Environment Production (terraform/environments/production/main.tf)
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "enterprise-terraform-state-prod"
key = "prod/terraform.tfstate"
region = "ap-southeast-1"
dynamodb_table = "terraform-lock-prod"
}
}
provider "aws" {
region = "ap-southeast-1"
}
module "vpc" {
source = "../../modules/vpc"
environment = "production"
cidr_block = "10.100.0.0/16"
}
module "web_server" {
source = "../../modules/ec2"
ami_id = "ami-0750a20ec6cb21633" # Ubuntu 22.04 LTS ap-southeast-1
instance_type = "c6i.xlarge"
subnet_id = module.vpc.public_subnet_id
security_group_ids = [module.vpc.web_sg_id]
environment = "production"
}
output "server_ip" {
value = module.web_server.public_ip
}
Ansible Playbook untuk Konfigurasi Web Stack (ansible/playbooks/webserver.yml)
---
- name: Provisioning Enterprise Web Stack
hosts: webservers
become: yes
vars:
php_version: "8.2"
roles:
- common
- nginx
- php-fpm
- redis
- security
Ansible Role: Nginx (ansible/roles/nginx/tasks/main.yml)
---
- name: Install Nginx Web Server
apt:
name: nginx
state: present
update_cache: yes
- name: Ensure Nginx is running and enabled at boot
service:
name: nginx
state: started
enabled: yes
- name: Deploy optimized Nginx configuration
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
validate: nginx -t
notify: restart nginx
- name: Deploy Virtual Host configuration for web application
template:
src: default.conf.j2
dest: /etc/nginx/sites-available/default
validate: nginx -t
notify: reload nginx
[!IMPORTANT] Pastikan parameter
validate: nginx -tselalu disertakan saat memperbarui konfigurasi Nginx via Ansible guna mencegah downtime fatal akibat kesalahan sintaks konfigurasi.
6. Bedah Kode & Penjelasan Detail Baris Kunci
- Terraform S3 Backend & DynamoDB Locking: Penggunaan
backend "s3"dengandynamodb_tablemencegah race condition ketika beberapa engineer atau CI pipeline mencoba melakukanterraform applysecara bersamaan. - Ansible Idempotency (
state: present/state: started): Memastikan bahwa playbook dapat dijalankan berkali-kali tanpa mengubah sistem jika kondisi yang diinginkan sudah tercapai. - Notifikasi Handler Ansible (
notify: restart nginx): Memastikan Nginx hanya direstart jika file template benar-benar mengalami perubahan, menghemat resource dan meminimalkan gangguan koneksi.
7. Skenario Produksi & Studi Kasus Dunia Nyata
Untuk melayani high concurrency (misalnya 10.000 req/s), arsitektur Terraform harus mendesain Auto Scaling Group (ASG) di belakang Application Load Balancer (ALB). Ansible kemudian melakukan provisioning pada AMI golden image atau menggunakan dynamic inventory untuk mengkonfigurasi instance baru yang lahir dari ASG.
Konfigurasi PHP-FPM dioptimalkan melalui Ansible template (/etc/php/8.2/fpm/pool.d/www.conf):
pm = dynamic
pm.max_children = 120
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
pm.max_requests = 1000
8. Common Pitfalls, Anti-Patterns & Solusi
- Anti-Pattern 1: Menyimpan Secret di dalam Git.
Solusi: Gunakan Terraform
sensitive = truedan Ansible Vault untuk mengenkripsi password database serta API keys. - Anti-Pattern 2: Hardcoding IP Address di Ansible Inventory. Solusi: Gunakan Terraform outputs yang diexport ke format JSON lalu dibaca oleh Ansible sebagai dynamic inventory.
- Anti-Pattern 3: Mengabaikan Terraform State Locking. Solusi: Selalu aktifkan DynamoDB lock pada backend S3 untuk menghindari korupsi state.
9. Benchmark, Metrik Kinerja & Tuning Performa
Lakukan pengujian beban menggunakan wrk setelah infrastruktur selesai di-deploy:
wrk -t12 -c400 -d30s http://<server_ip>/
Tuning Parameter Sistem Linux (/etc/sysctl.conf yang dikelola via Ansible):
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 8192
fs.file-max = 2097152
10. Checklist Penerapan Produksi & Kesimpulan
- Terraform state disimpan secara remote dan terenkripsi.
- DynamoDB locking aktif.
- Ansible playbooks bersifat idempotent.
- UFW Firewall dan Fail2ban aktif di seluruh node.
- Backup otomatis database dan S3 versioning diaktifkan.
- CI/CD pipeline memvalidasi
terraform plansebelumapply.
Dengan memadukan ketangguhan Terraform dalam manajemen sumber daya awan dan keandalan Ansible dalam manajemen konfigurasi aplikasi, organisasi enterprise dapat mencapai tingkat otomatisasi, keamanan, dan skalabilitas tertinggi.