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

Automating Enterprise Infrastructure with Terraform & Ansible

⏱️ 15 menit baca β€’ πŸ“… 15 Oct 2026 β€’ πŸ‘οΈ 1 views
Automating Enterprise Infrastructure with Terraform & Ansible

Automating Enterprise Infrastructure with Terraform & Ansible

1. Konteks Industri & Analisis Akar Masalah

Di era komputasi modern, pengelolaan infrastruktur berbasis Point-and-Click melalui konsol cloud (AWS Console, GCP Console, atau vSphere UI) adalah sebuah anti-pattern yang berbahaya bagi stabilitas enterprise. Pendekatan manual ini memicu fenomena Configuration Drift, di mana kondisi server di lingkungan produksi menyimpang secara liar dari dokumentasi akibat perubahan insidental (hotfix langsung di server via SSH) yang tidak terlacak. Bottleneck operasional ini berdampak langsung pada lambatnya waktu Time-to-Market, tingginya risiko human error, dan lamanya waktu pemulihan (Mean Time to Recovery / MTTR) saat terjadi bencana infrastruktur.

Sebelum adopsi Infrastructure as Code (IaC) secara komprehensif, tim infrastruktur enterprise sering kali terjebak dalam siklus reaktif: provisioning server memakan waktu berhari-hari, konfigurasi web server (Nginx/Apache), runtime (PHP-FPM/Node.js/Go), database (MySQL/MariaDB), dan sistem caching (Redis) dilakukan secara manual menggunakan skrip Bash yang rapuh dan tidak memiliki mekanisme idempotency. Hal ini menyebabkan inkonsistensi antara lingkungan development, staging, dan production.

Setelah menerapkan otomatisasi penuh menggunakan Terraform untuk provisioning fondasi infrastruktur (VPC, Subnet, Compute Instances, Security Groups, S3 Buckets) dan Ansible untuk konfigurasi manajemen konfigurasi serta deployment aplikasi (Nginx, SSL/TLS, Postfix SMTP Relay, Fail2ban, Supervisor), organisasi mendapatkan transformasi radikal. Infrastruktur menjadi sepenuhnya reproducible, terdokumentasi dalam bentuk kode version-controlled (Git), dan dapat di-deploy ulang dari nol dalam hitungan menit tanpa intervensi manual yang rentan kesalahan.

2. Konsep Inti & Deep Dive Arsitektur

Integrasi Terraform dan Ansible dirancang berdasarkan prinsip pembagian tugas yang tegas (Separation of Concerns). Terraform bertanggung jawab penuh pada lapisan Provisioning (Infrastruktur IaaS/PaaS/SaaS), sedangkan Ansible mengambil alih pada lapisan Configuration Management dan Application Deployment.

+-------------------------------------------------------------------------+
|                        Developer / GitOps CI/CD                         | 
+-------------------------------------------------------------------------+
                                     |
                                     v
+-------------------------------------------------------------------------+ 
|                         Terraform (Provisioning)                        |
|  - AWS VPC, Subnets, Internet Gateway, Route Tables                     |
|  - EC2 Instances, Security Groups, EBS Volumes                          |
|  - S3 Object Storage, Cloudflare DNS Records                            |
+-------------------------------------------------------------------------+
                                     |
             Generates dynamic inventory (hosts.ini / API)
                                     v
+-------------------------------------------------------------------------+ 
|                   Ansible (Configuration & Deployment)                  |
|  - System Hardening (UFW, Fail2ban, SSH Config)                         |
|  - Web Stack Setup (Nginx, PHP-FPM, Node.js, Go binaries)               |
|  - Databases & Caching (MySQL, Redis, Supervisor, Cron)                 |
|  - Security & SSL (Let's Encrypt Certbot, Postfix SMTP Relay)           |
+-------------------------------------------------------------------------+

Alur kerja eksekusi dimulai saat engineer mengeksekusi terraform apply. Terraform berkomunikasi dengan Cloud Provider API untuk membangun sumber daya komputasi dan jaringan. Setelah instance aktif, Terraform dapat secara otomatis menghasilkan Dynamic Inventory (atau menuliskan IP publik ke dalam file hosts.ini). Selanjutnya, Ansible dijalankan untuk melakukan koneksi SSH ke target instance, mengecek status sistem, dan menerapkan Ansible Playbooks yang bersifat idempotentβ€”artinya skrip dapat dijalankan berulang kali tanpa mengubah sistem yang sudah berada dalam kondisi yang diinginkan.

3. Perbandingan Komparatif / Analisis Pendekatan

Untuk memahami mengapa kombinasi Terraform dan Ansible menjadi standar industri enterprise, mari kita lakukan analisis komparatif mendalam terhadap berbagai pendekatan otomatisasi infrastruktur.

Parameter Komparasi Terraform + Ansible (Hybrid) Pure Terraform (Cloud-Init / Null Resource) Chef / Puppet / SaltStack (Legacy CM) Manual ClickOps / Custom Bash Scripts
Fokus Utama Provisioning + Config Management Provisioning murni Configuration Management Ad-hoc execution
Idempotency Sempurna (Terraform state + Ansible modules) Terbatas pada cloud resource Sempurna untuk OS config Buruk / Sering merusak sistem
Kurva Belajar Menengah (HCL + YAML) Rendah hingga Menengah (HCL) Tinggi (Ruby/DSL yang kompleks) Sangat Rendah (Awal), Sangat Tinggi (Maintenance)
Overhead Sumber Daya Rendah (Agentless SSH) Rendah Tinggi (Membutuhkan agent daemon di server) Minimal secara tool, tinggi secara waktu operasional
State Management Terraform State (.tfstate) + Remote Backend Terraform State (.tfstate) Centralized Server (Chef Server / Salt Master) Tidak ada (manual tracking)
Kecepatan Rollout Cepat (Parallel execution via Ansible forks) Sangat Cepat Lambat (Agent polling interval) Sangat Lambat & Rentan Error

[!IMPORTANT] Jangan pernah menggunakan Terraform untuk manajemen file konfigurasi aplikasi internal berskala besar (seperti nginx.conf atau php.ini) secara langsung menggunakan local-exec atau null_resource. Batasi Terraform hanya untuk infrastruktur dasar, dan serahkan manajemen konfigurasi sistem operasi serta aplikasi sepenuhnya kepada Ansible.

4. Prasyarat Sistem & Persiapan Lingkungan

Sebelum membangun codebase otomatisasi, pastikan environment mesin pengembang (control node) memenuhi spesifikasi teknis berikut:

  • Operating System: Linux Ubuntu 22.04 LTS / macOS Ventura+ / WSL2 Ubuntu.
  • Terraform Binary: Versi >= 1.5.0.
  • Ansible Core: Versi >= 2.15.
  • Cloud Access: Akun AWS / Proxmox / DigitalOcean dengan kredensial API yang valid (diatur melalui environment variables seperti AWS_ACCESS_KEY_ID dan AWS_SECRET_ACCESS_KEY).
  • SSH Key Pair: Kunci SSH privat (id_rsa / id_ed25519) yang telah didaftarkan pada cloud provider untuk autentikasi instance.

Struktur direktori proyek enterprise yang direkomendasikan:

enterprise-infrastructure/
β”œβ”€β”€ terraform/
β”‚   β”œβ”€β”€ environments/
β”‚   β”‚   β”œβ”€β”€ production/
β”‚   β”‚   β”‚   β”œβ”€β”€ main.tf
β”‚   β”‚   β”‚   β”œβ”€β”€ variables.tf
β”‚   β”‚   β”‚   β”œβ”€β”€ outputs.tf
β”‚   β”‚   β”‚   └── backend.tf
β”‚   β”‚   └── staging/
β”‚   └── modules/
β”‚       β”œβ”€β”€ vpc/
β”‚       β”œβ”€β”€ ec2/
β”‚       └── database/
└── ansible/
    β”œβ”€β”€ inventory/
    β”‚   └── production/
    β”‚       └── hosts.ini
    β”œβ”€β”€ playbooks/
    β”‚   β”œβ”€β”€ site.yml
    β”‚   └── webserver.yml
    └── roles/
        β”œβ”€β”€ common/
        β”œβ”€β”€ nginx/
        β”œβ”€β”€ php-fpm/
        β”œβ”€β”€ mysql/
        └── redis/

5. Panduan Implementasi Langkah demi Langkah

Langkah 1: Modul Terraform untuk Provisioning Server Web & Database

Kita mulai dengan membuat modul Terraform untuk menginisialisasi infrastruktur dasar. Buat file terraform/modules/ec2/main.tf:

terraform {
  required_version = ">= 1.5.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

resource "aws_security_group" "web_sg" {
  name        = "${var.environment}-web-sg"
  description = "Security group for web and database servers"
  vpc_id      = var.vpc_id

  ingress {
    description = "Allow SSH from Admin CIDR"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = [var.admin_cidr]
  }

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

  ingress {
    description = "Allow HTTPS"
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    description = "Allow all outbound traffic"
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

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

resource "aws_instance" "web_server" {
  ami                    = var.ami_id
  instance_type          = var.instance_type
  subnet_id              = var.subnet_id
  vpc_security_group_ids = [aws_security_group.web_sg.id]
  key_name               = var.key_name

  root_block_device {
    volume_size           = 50
    volume_type           = "gp3"
    encrypted             = true
    delete_on_termination = false
  }

  tags = {
    Name        = "${var.environment}-web-node-01"
    Environment = var.environment
    Role        = "web-db"
  }
}

output "web_public_ip" {
  value       = aws_instance.web_server.public_ip
  description = "Public IP address of the provisioned web server"
}

Buat file variabel pendukung di terraform/modules/ec2/variables.tf:

variable "environment" {
  type        = string
  description = "Deployment environment name"
}

variable "vpc_id" {
  type        = string
  description = "VPC ID where the instance will be deployed"
}

variable "subnet_id" {
  type        = string
  description = "Subnet ID"
}

variable "admin_cidr" {
  type        = string
  description = "CIDR block allowed for SSH access"
}

variable "ami_id" {
  type        = string
  description = "AMI ID for Ubuntu 22.04 LTS"
}

variable "instance_type" {
  type        = string
  default     = "t3.medium"
}

variable "key_name" {
  type        = string
  description = "AWS EC2 Key Pair name"
}

Langkah 2: Konfigurasi Ansible Playbook & Roles

Setelah instance aktif, Ansible mengambil alih untuk menginstal Nginx, PHP-FPM, MySQL, dan Redis. Buat file Inventory di ansible/inventory/production/hosts.ini:

[webservers]
production-web-01 ansible_host=203.0.113.50 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/production_key.pem

[databases]
production-web-01 ansible_host=203.0.113.50 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/production_key.pem

[all:vars]
ansible_python_interpreter=/usr/bin/python3

Buat Playbook utama di ansible/playbooks/site.yml:

---
- name: Provision Enterprise Web & Database Node
  hosts: webservers
  become: yes
  gather_facts: yes
  
  roles:
    - common
    - security
    - nginx
    - php_fpm
    - mysql
    - redis
    - supervisor

Mari kita buat implementasi salah satu role krusial, yaitu Nginx, di ansible/roles/nginx/tasks/main.yml:

---
- name: Update apt cache and install Nginx
  apt:
    name: nginx
    state: present
    update_cache: yes

- name: Ensure Nginx service is started and enabled
  service:
    name: nginx
    state: started
    enabled: yes

- name: Deploy custom enterprise Nginx configuration
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: '0644'
  notify: Restart Nginx

- name: Deploy default virtual host configuration
  template:
    src: default.conf.j2
    dest: /etc/nginx/sites-available/default
    owner: root
    group: root
    mode: '0644'
  notify: Reload Nginx

Tambahkan Handler untuk Nginx di ansible/roles/nginx/handlers/main.yml:

---
- name: Restart Nginx
  service:
    name: nginx
    state: restarted

- name: Reload Nginx
  service:
    name: nginx
    state: reloaded

Buat template virtual host Nginx berperforma tinggi di ansible/roles/nginx/templates/default.conf.j2:

server {
    listen 80;
    server_name {{ domain_name | default('_') }};
    root /var/www/html/public;

    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;

    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_read_timeout 300;
    }

    location ~* \.(jpg|jpeg|gif|png|css|js|ico|webp|svg|woff|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }

    location ~ /\.ht {
        deny all;
    }
}

6. Bedah Kode & Penjelasan Detail Baris Kunci

Analisis mendalam terhadap komponen kode kritis yang telah kita buat:

  1. Blok root_block_device pada Terraform (aws_instance): Parameter volume_size = 50 dengan volume_type = "gp3" memastikan performa IOPS baseline sebesar 3,000 IOPS tanpa biaya tambahan dari provisioned IOPS. Atribut encrypted = true adalah mandat kepatuhan keamanan enterprise (compliance) untuk mengenkripsi data saat diam (data at rest) menggunakan AWS KMS default.

  2. Blok template pada Ansible Nginx Role: Modul template menerjemahkan file Jinja2 (.j2) di local machine menjadi file konfigurasi aktual di remote server. Penggunaan variabel {{ domain_name }} memungkinkan reuse playbook yang sama untuk staging dan production tanpa hardcoding nilai.

  3. Blok fastcgi_pass unix:/var/run/php/php8.2-fpm.sock: Menggunakan Unix Domain Socket alih-alih TCP Loopback (127.0.0.1:9000) untuk komunikasi antara Nginx dan PHP-FPM. Pendekatan ini memangkas latensi jaringan lokal karena komunikasi terjadi langsung melalui memori kernel sistem operasi, meningkatkan throughput hingga 15-20% pada beban request tinggi.

7. Skenario Produksi & Studi Kasus Dunia Nyata

Dalam skenario enterprise berbeban tinggi (High Concurrency E-commerce Flash Sale), arsitektur tunggal di atas tidak akan mencukupi. Kita perlu memperluas Terraform untuk menerapkan Auto Scaling Group (ASG) di belakang Application Load Balancer (ALB), serta memisahkan database ke managed service (AWS RDS MySQL Multi-AZ) dan Redis ke cluster terdistribusi (AWS ElastiCache).

Ansible berperan dalam menyiapkan Golden AMI (Amazon Machine Image). Alih-alih mengonfigurasi server saat booting secara real-time, kita menggunakan Packer & Ansible untuk membuat image mesin yang sudah di-hardening dan terinstal seluruh stack aplikasi sebelumnya. Ketika lonjakan traffic terjadi, AWS Auto Scaling dapat meluncurkan node baru dalam waktu kurang dari 60 detik yang sudah siap melayani traffic secara instan.

8. Common Pitfalls, Anti-Patterns & Solusi

  • Anti-Pattern 1: Menyimpan Terraform State File secara Lokal

    • Masalah: Menyimpan file terraform.tfstate di mesin lokal menyebabkan korupsi state saat dikerjakan oleh tim kolaboratif dan membocorkan rahasia kredensial.
    • Solusi: Selalu gunakan Remote Backend terpusat seperti AWS S3 dengan State Locking via DynamoDB, disertai enkripsi sisi server (Server-Side Encryption).
  • Anti-Pattern 2: Non-Idempotent Ansible Tasks

    • Masalah: Menggunakan modul shell atau command di Ansible untuk menjalankan perintah mentah tanpa conditionals (creates atau removes), mengakibatkan playbook gagal atau mengubah status sistem setiap kali dijalankan.
    • Solusi: Selalu prioritaskan penggunaan built-in modules Ansible (apt, service, template, copy) yang secara inheren bersifat idempotent.
  • Anti-Pattern 3: Hardcoding Secret Keys di Playbook

    • Masalah: Meletakkan password database atau API token secara plain text di dalam file YAML playbook.
    • Solusi: Gunakan Ansible Vault untuk mengenkripsi file variabel sensitif secara kriptografis (ansible-vault encrypt vars/secrets.yml).

9. Benchmark, Metrik Kinerja & Tuning Performa

Setelah infrastruktur otomatis selesai di-deploy, lakukan pengujian beban (load testing) menggunakan tool modern seperti k6 atau wrk. Contoh skrip pengujian k6 untuk menguji endpoint web aplikasi (script.js):

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

export const options = {
  stages: [
    { duration: '30s', target: 100 }, // Ramp-up ke 100 pengguna
    { duration: '1m', target: 500 },  // Pertahankan 500 pengguna
    { duration: '30s', target: 0 },   // Ramp-down
  ],
};

export default function () {
  const res = http.get('http://203.0.113.50/');
  check(res, {
    'status is 200': (r) => r.status === 200,
    'response time < 200ms': (r) => r.timings.duration < 200,
  });
  sleep(1);
}

Kernel Tuning Parameter (sysctl.conf) yang wajib diterapkan melalui Ansible untuk menangani koneksi TCP masif:

# /etc/sysctl.d/99-enterprise-tuning.conf
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
net.core.netdev_max_backlog = 16384

Terapkan perubahan ini melalui Ansible agar kernel Linux sanggup menahan puluhan ribu koneksi konkuren tanpa mengalami Connection Timed Out.

10. Checklist Penerapan Produksi & Kesimpulan

Sebelum meluncurkan infrastruktur otomatis ini ke lingkungan produksi live, pastikan seluruh item dalam checklist berikut telah terpenuhi:

  • Terraform Remote Backend dikonfigurasi dengan S3 + DynamoDB Locking.
  • Semua file variabel sensitif Ansible telah dienkripsi menggunakan Ansible Vault.
  • Firewall (UFW / Security Groups) dikunci ketat; hanya port 80, 443, dan port SSH kustom yang terbuka.
  • Fail2ban diaktifkan untuk mencegah serangan brute-force pada layanan SSH dan Nginx.
  • Sertifikat SSL/TLS Let's Encrypt terpasang dengan mekanisme auto-renewal via cron/systemd timer.
  • Sistem monitoring (Prometheus + Node Exporter) terintegrasi untuk memantau penggunaan CPU, RAM, Disk I/O, dan Network.
  • Backup otomatis database harian terjadwal dan diuji restore-nya secara berkala.

Dengan mengawinkan kekuatan provisioning deklaratif dari Terraform dan ketepatan konfigurasi prosedural-idempotent dari Ansible, organisasi Anda tidak hanya mencapai efisiensi operasional yang masif, tetapi juga membangun fondasi infrastruktur web enterprise yang tahan banting, skalabel, dan siap menghadapi dinamika bisnis digital masa depan.

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