L
Infrastructure as Code (IaC) • Literally Web ID

Automasi Infrastruktur Skala Enterprise Menggunakan Terraform & Ansible

⏱️ 18 menit baca • 📅 15 Oct 2026 • 👁️ 1 views
Automasi Infrastruktur Skala Enterprise Menggunakan Terraform & Ansible

1. Konteks Industri & Analisis Akar Masalah

Di era komputasi modern, infrastruktur berbasis manual provisioning atau klik-klik melalui konsol cloud (AWS Console, GCP Console) sudah menjadi anti-pattern yang berbahaya bagi skalabilitas enterprise. Pendekatan manual meninggalkan jejak configuration drift, di mana server produksi berbeda dari staging akibat perubahan hotfix yang tidak tercatat, menciptakan kerentanan keamanan dan kegagalan sistem yang sulit direproduksi.

Bottleneck utama pada arsitektur web skala enterprise modern terletak pada kecepatan pemulihan bencana (Disaster Recovery), konsistensi lingkungan deployment, dan kepatuhan terhadap standar keamanan yang ketat. Jika sebuah klaster web server yang menjalankan Nginx, PHP-FPM, Node.js API, dan Redis Cache mengalami kegagalan, mengandalkan sysadmin untuk merakit ulang secara manual membutuhkan waktu berjam-jam, bahkan hari.

[!IMPORTANT] Pendekatan modern menuntut pemisahan tugas yang tegas: Terraform bertanggung jawab untuk memprovisi Infrastructure as Code (IaC) yang bersifat Immutable, sedangkan Ansible melakukan Configuration Management konvergen untuk menyiapkan runtime environment secara deterministik.

Kondisi Sebelum vs Sesudah Automasi Skala Enterprise

Parameter Sebelum (Manual / Semi-Automated) Sesudah (Terraform + Ansible Immutable Pipeline)
Waktu Provisioning 4 - 8 Jam per server (Manual setup OS, Nginx, PHP, Redis) 3 - 5 Menit (Fully automated pipeline)
Configuration Drift Tinggi (Sering terjadi modifikasi manual via SSH) Nol (Setiap server baru adalah klon identik, penggantian total via replace)
Keamanan & Compliance Rentan human error (Lupa tutup port, izin file salah) Terstandarisasi via kode terverifikasi (GitOps & Static Analysis)
Skalabilitas Terbatas pada kapasitas fisik atau kesiapan tim ops Elastis, auto-scaling instan dengan konfigurasi zero-touch

2. Konsep Inti & Deep Dive Arsitektur

Untuk mencapai automasi tingkat enterprise, kita harus menggabungkan dua filosofi: Declarative Provisioning (Terraform) dan Idempotent Configuration (Ansible).

Alur Eksekusi Sistem (Pipeline Under The Hood)

+--------------------------------------------------------------------------+ 
|                         Developer Commit to Git                          | 
+--------------------------------------------------------------------------+ 
                                     |
                                     v
+--------------------------------------------------------------------------+ 
|                        CI/CD Pipeline Triggered                          | 
+--------------------------------------------------------------------------+ 
         |                                                 |
         v (Step 1)                                        v (Step 2)
+-------------------------------+               +--------------------------+
|    Terraform Plan / Apply     | ------------> | Dynamic Inventory Gen.   |
| (AWS VPC, EC2, S3, RDS, Redis)|               | (Extracts Public IPs)    |
+-------------------------------+               +--------------------------+
                                                           |
                                                           v (Step 3)
                                                +--------------------------+
                                                |      Ansible Playbook    |
                                                | (Nginx, PHP-FPM, UFW,    |
                                                |  Fail2ban, SSL Certs)    |
                                                +--------------------------+
                                                           |
                                                           v (Step 4)
                                                +--------------------------+
                                                | Production-Ready Web Node|
                                                +--------------------------+
  1. Terraform Phase: Membangun fondasi infrastruktur cloud secara deklaratif. Terraform mengirimkan API call ke provider (AWS/GCP/Azure) untuk membuat Virtual Private Cloud (VPC), Subnet, Security Groups, EC2 Instances, S3 Buckets untuk asset, dan RDS/ElastiCache.
  2. Dynamic Inventory Generation: Mengambil output IP dari Terraform state untuk dimasukkan secara otomatis ke memori Ansible.
  3. Ansible Phase: Masuk melalui SSH, melakukan hardening OS Linux, instalasi web stack (Nginx, PHP-FPM, Node.js), konfigurasi reverse proxy, pengaturan SSL/TLS via Let's Encrypt, setup Fail2ban, dan konfigurasi rute DNS.

3. Perbandingan Komparatif / Analisis Pendekatan

Dalam membangun automasi enterprise, seringkali muncul perdebatan mengenai pemilihan tool. Berikut adalah analisis mendalam:

Aspek Perbandingan Terraform (HashiCorp) Ansible (Red Hat) Bash / Shell Scripts
Paradigma Deklaratif (Desired State) Imperatif/Deklaratif (Procedural/Idempotent) Imperatif murni
Manajemen State Menggunakan State File (terraform.tfstate) Agentless, tidak memiliki state file pusat Tidak ada
Fokus Utama Cloud Infrastructure (VPC, Compute, DB) OS Configuration, Software Provisioning Quick ad-hoc tasks
Konsumsi CPU/RAM Ringan (Go binary) Sangat Ringan (Python agentless via SSH) Minimal
Kurva Belajar Menengah (HCL syntax) Rendah ke Menengah (YAML syntax) Sangat Rendah (namun berisiko tinggi)
Trade-off Utama Kompleksitas penanganan state locking Kurang ideal untuk pembuatan Cloud VPC kompleks Tidak dapat di-maintain (Spaghetti code)

[!TIP] Jangan pernah menggunakan Ansible untuk memprovisi Cloud VPC atau Security Groups dalam skala besar karena tidak memiliki manajemen state tracking yang kuat seperti Terraform. Sebaliknya, jangan gunakan Terraform untuk mengatur file konfigurasi internal aplikasi (seperti nginx.conf atau php.ini) karena akan memperlambat siklus iterasi apply.


4. Prasyarat Sistem & Persiapan Lingkungan

Sebelum menyelam ke kode, pastikan lingkungan kerja (Control Machine) Anda memenuhi spesifikasi berikut:

  • OS: Ubuntu 22.04 LTS / macOS Ventura+
  • Terraform: Versi >= 1.5.0
  • Ansible: Versi >= 2.14+
  • AWS CLI: Terkonfigurasi dengan profil IAM yang memiliki akses Administrator / PowerUser.
  • SSH Keys: Pasangan kunci RSA/Ed25519 untuk autentikasi server.

Verifikasi instalasi dengan perintah berikut:

terraform -version
ansible --version
aws --version

Pastikan direktori kerja Anda terstruktur secara modular:

enterprise-infrastructure/
├── terraform/
│   ├── main.tf
│   ├── variables.tf
│   ├── outputs.tf
│   └── backend.tf
└── ansible/
    ├── inventory/
    │   └── dynamic_inventory.aws_ec2.yml
    ├── playbooks/
    │   └── site.yml
    └── roles/
        ├── common/
        ├── nginx/
        └── php-fpm/

5. Panduan Implementasi Langkah demi Langkah

Langkah 1: Konfigurasi Terraform untuk Provisioning Cloud

Buat file terraform/backend.tf untuk menyimpan state secara aman di S3 dengan penguncian DynamoDB.

terraform {
  required_version = ">= 1.5.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  backend "s3" {
    bucket         = "enterprise-terraform-state-bucket-prod"
    key            = "web-infrastructure/terraform.tfstate"
    region         = "ap-southeast-1"
    dynamodb_table = "terraform-lock-table"
    encrypt        = true
  }
}

provider "aws" {
  region = "ap-southeast-1"
  default_tags {
    tags {
      Environment = "Production"
      ManagedBy   = "Terraform"
      Project     = "EnterpriseWeb"
    }
  }
}

Buat file terraform/main.tf untuk mendefinisikan infrastruktur jaringan dan EC2 instance.

resource "aws_vpc" "main" {
  cidr_block           = "10.100.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name = "prod-vpc"
  }
}

resource "aws_subnet" "public" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.100.1.0/24"
  map_public_ip_on_launch = true
  availability_zone       = "ap-southeast-1a"

  tags = {
    Name = "prod-public-subnet"
  }
}

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

  tags = {
    Name = "prod-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 = "prod-public-rt"
  }
}

resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}

resource "aws_security_group" "web_sg" {
  name        = "prod-web-sg"
  description = "Allow HTTP, HTTPS, and SSH"
  vpc_id      = aws_vpc.main.id

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

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

  ingress {
    description = "SSH from Admin Bastion"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["203.0.113.50/32"] # Ganti dengan IP Bastion Host Anda
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

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"] # Canonical
}

resource "aws_instance" "web_server" {
  ami                    = data.aws_ami.ubuntu.id
  instance_type          = "t3.medium"
  subnet_id              = aws_subnet.public.id
  vpc_security_group_ids = [aws_security_group.web_sg.id]
  key_name               = "prod-ssh-key"

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

  tags = {
    Name = "prod-web-node-01"
    Role = "webserver"
  }
}

output "web_instance_ip" {
  value       = aws_instance.web_server.public_ip
  description = "Public IP of the web server for Ansible execution"
}

Jalankan perintah Terraform untuk memprovisi:

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

Langkah 2: Konfigurasi Ansible untuk Web Stack

Buat file inventory dinamis ansible/inventory/dynamic_inventory.aws_ec2.yml agar Ansible secara otomatis mengenali EC2 instance yang baru dibuat oleh Terraform.

plugin: amazon.aws.aws_ec2
regions:
  - ap-southeast-1
filters:
  tag:Role: webserver
  instance-state-name: running
hostnames:
  - ip-address
keyed_groups:
  - key: tags.Role
    prefix: role

Buat playbook utama ansible/playbooks/site.yml:

---
- name: Provision Enterprise Web Stack
  hosts: role_webserver
  become: yes
  vars:
    php_version: "8.2"
  roles:
    - common
    - nginx
    - php-fpm

Buat peran Ansible untuk Nginx (ansible/roles/nginx/tasks/main.yml):

---
- name: Install Nginx Web Server
  apt:
    name: nginx
    state: present
    update_cache: yes

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

- name: Deploy Enterprise Nginx Virtual Host Config
  template:
    src: enterprise_vhost.conf.j2
    dest: /etc/nginx/sites-available/enterprise.conf
    owner: root
    group: root
    mode: '0644'
  notify: Restart Nginx

- name: Enable Enterprise Vhost
  file:
    src: /etc/nginx/sites-available/enterprise.conf
    dest: /etc/nginx/sites-enabled/enterprise.conf
    state: link
  notify: Restart Nginx

- name: Remove default Nginx site
  file:
    path: /etc/nginx/sites-enabled/default
    state: absent
  notify: Restart Nginx

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

Buat template virtual host Nginx (ansible/roles/nginx/templates/enterprise_vhost.conf.j2):

server {
    listen 80;
    server_name enterprise.internal;
    root /var/www/html;

    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;
    add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" 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/php{{ php_version }}-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

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

Jalankan Ansible Playbook:

cd ansible/
ansible-playbook -i inventory/dynamic_inventory.aws_ec2.yml playbooks/site.yml --private-key=~/.ssh/prod-ssh-key.pem -u ubuntu

6. Bedah Kode & Penjelasan Detail Baris Kunci

  1. backend "s3" pada Terraform: Konfigurasi ini krusial untuk lingkungan enterprise karena menyimpan file status (terraform.tfstate) secara terpusat di AWS S3 dengan dukungan DynamoDB State Locking. Tanpa ini, jika dua engineer menjalankan terraform apply secara bersamaan, korupsi state akan terjadi.
  2. root_block_device { encrypted = true }: Memastikan bahwa volume root EBS dienkripsi menggunakan AWS KMS secara default, memenuhi standar kepatuhan regulasi finansial dan enterprise (SOC2, ISO 27001).
  3. template module di Ansible: Menggunakan Jinja2 template (enterprise_vhost.conf.j2) memungkinkan injeksi variabel dinamis (seperti versi PHP) secara fleksibel tanpa menulis ulang file konfigurasi manual.
  4. Security Headers di Nginx: Baris add_header X-Frame-Options dan kawan-kawan memperkuat postur keamanan web server terhadap serangan umum seperti Clickjacking, Cross-Site Scripting (XSS), dan MIME-type sniffing.

7. Skenario Produksi & Studi Kasus Dunia Nyata

Pada lingkungan e-commerce skala besar yang menghadapi flash sale (lonjakan traffic hingga 100.000 concurrent request dalam 1 menit), arsitektur statis tunggal akan runtuh.

Strategi Solusi Enterprise

  • Auto Scaling Group (ASG): Menggunakan Terraform untuk mendefinisikan AWS Launch Template dan Auto Scaling Group dengan metrik CPU Utilization > 70% sebagai pemicu penambahan node.
  • Dynamic Inventory Integration: Ansible dikonfigurasi untuk berjalan secara otomatis via webhook (atau AWS Systems Manager / SSM Agent) setiap kali node baru di-spawn oleh ASG, memastikan node baru langsung terinstal web stack yang identik dalam kurun waktu < 120 detik.
  • Load Balancing & Edge Caching: Cloudflare diletakkan di depan AWS ALB (Application Load Balancer) untuk menahan DDOS dan melakukan caching asset statis di edge network.

8. Common Pitfalls, Anti-Patterns & Solusi

  • Anti-Pattern 1: Menyimpan Secret di dalam Terraform/Ansible Code.
    • Solusi: Selalu gunakan AWS Secrets Manager, HashiCorp Vault, atau Ansible Vault untuk mengenkripsi kredensial sensitif seperti password database dan API token.
  • Anti-Pattern 2: Hardcoding IP Address pada Ansible Inventory.
    • Solusi: Manfaatkan Dynamic Inventory Plugins (seperti amazon.aws.aws_ec2) agar inventory selalu sinkron secara real-time dengan status cloud.
  • Pitfall 3: Mengabaikan State Locking.
    • Solusi: Selalu aktifkan DynamoDB table untuk locking pada Terraform S3 backend.

9. Benchmark, Metrik Kinerja & Tuning Performa

Untuk menguji ketahanan infrastruktur yang telah diotomasi, lakukan pengujian beban menggunakan wrk atau k6 terhadap web server yang baru diprovisi.

wrk -t12 -c400 -d30s http://<YOUR_WEB_SERVER_IP>/

Parameter Tuning Lanjutan pada Linux Kernel (/etc/sysctl.conf):

Tambahkan konfigurasi berikut melalui Ansible untuk menangani koneksi konkurensi tinggi:

# Meningkatkan batas maximum file descriptors
fs.file-max = 2097152

# Optimasi TCP backlog dan SYN cookies
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 8192

# Mengaktifkan reuse TIME_WAIT sockets
net.ipv4.tcp_tw_reuse = 1

10. Checklist Penerapan Produksi & Kesimpulan

Sebelum merilis infrastruktur ini ke lingkungan Live Production, pastikan Anda telah mencentang seluruh daftar periksa berikut:

  • State Terraform disimpan di remote backend yang terenkripsi dan terlindung lock table.
  • Seluruh password, salt, dan secret telah dienkripsi menggunakan Ansible Vault atau Secret Manager.
  • Firewall (Security Groups & UFW) membatasi akses hanya ke port yang dibutuhkan (80, 443, SSH terbatas).
  • Fail2ban aktif untuk mencegah serangan brute-force pada SSH dan web login.
  • Backup otomatis EBS snapshot terjadwal menggunakan AWS Data Lifecycle Manager (DLM).
  • Pengujian Disaster Recovery (menghancurkan dan membangun kembali klaster via pipeline) telah berhasil dilakukan tanpa intervensi manual.

Dengan mengintegrasikan Terraform dan Ansible secara disiplin, organisasi Anda tidak hanya mencapai efisiensi operasional yang masif, tetapi juga membangun ketahanan sistem yang tahan terhadap kegagalan infrastruktur skala enterprise.

🏷️ Tags: #Devops #Terraform #Ansible #Infrastructure As Code #Cloud Architecture