L
Infrastructure as Code (IaC) • Literally Web ID

Automated Infrastructure Provisioning: Zero-Downtime Deployment dengan Terraform & Ansible

⏱️ 20 menit baca • 📅 13 Oct 2026 • 👁️ 1 views
Automated Infrastructure Provisioning: Zero-Downtime Deployment dengan Terraform & Ansible

Automated Infrastructure Provisioning: Zero-Downtime Deployment dengan Terraform & Ansible

1. Konteks Industri & Analisis Akar Masalah

Dalam lanskap arsitektur web modern, kompleksitas manajemen infrastruktur telah bergeser dari pendekatan pet-server manual menuju paradigma cattle-infrastructure yang sepenuhnya diotomatisasi. Di lingkungan enterprise yang menuntut high availability 99.99%, pengelolaan server secara manual melalui Secure Shell (SSH) tidak lagi dapat ditoleransi. Pendekatan tradisional rentan terhadap configuration drift—yakni kondisi di mana konfigurasi antar server produksi menyimpang secara perlahan akibat perubahan manual yang tidak tercatat, menyebabkan inkonsistensi lingkungan antara staging dan production.

Bottleneck performa dan keamanan yang sering muncul di dunia nyata meliputi:

  • Inkonsistensi Environment: Perbedaan versi paket utilitas sistem, ekstensi PHP-FPM, atau konfigurasi Nginx antara server lokal pengembang dan production.
  • Downtime saat Deployment: Proses rolling update yang dilakukan secara manual sering kali memicu dropped connections pada aplikasi Node.js atau Go, serta kegagalan koneksi database MariaDB akibat pemutusan koneksi mendadak.
  • Kerentanan Keamanan: Kegagalan menerapkan hardened security baseline secara serentak, seperti pengetatan aturan UFW, konfigurasi Fail2ban untuk mencegah brute-force SSH, dan rotasi sertifikat SSL/TLS Let's Encrypt yang terlambat.

Kondisi Sebelum vs Sesudah Penerapan

  • Sebelum (Manual & Ad-hoc): Provisioning VM memakan waktu berhari-hari, deploy aplikasi menggunakan skrip bash kustom yang rapuh (fragile), risiko human error tinggi, dan pemulihan bencana (disaster recovery) memakan waktu berjam-jam.
  • Sesudah (Terraform & Ansible Pipeline): Seluruh infrastruktur (VPC, Subnet, Security Groups, Compute Instances, S3 Storage, DNS Record Cloudflare) didefinisikan sebagai kode (Infrastructure as Code). Provisioning dan konfigurasi OS hingga aplikasi berjalan otomatis dalam hitungan menit secara konsisten dan reproducible.

2. Konsep Inti & Deep Dive Arsitektur

Automasi infrastruktur modern memisahkan dua fase krusial: Provisioning dan Configuration Management. Terraform menangani lapisan infrastruktur dasar (IaaS/PaaS), sementara Ansible mengambil alih lapisan sistem operasi dan perangkat lunak di dalam instance tersebut.

Alur Eksekusi Arsitektur (ASCII Flow Chart)

+-----------------------+       +------------------------+
|   Developer / CI/CD   | ----> |     Terraform CLI      |
+-----------------------+       +------------------------+
                                            |
                                            v (Provisioning API)
                                +------------------------+
                                | Cloud Provider (AWS/GCP)|
                                +------------------------+
                                            |
                                            v (Dynamic Inventory)
+-----------------------+       +------------------------+
|    Ansible Playbook   | <---- | Target Compute Instance|
+-----------------------+       +------------------------+
        |
        +---> Konfigurasi Nginx, PHP-FPM, Redis, MySQL, Fail2ban
        +---> Setup SSL Let's Encrypt, Supervisor, Postfix Relay
  1. Terraform Phase: Membaca berkas deklaratif (.tf), membuat execution plan (terraform plan), dan menerapkannya (terraform apply) untuk membuat infrastruktur fisik atau virtual.
  2. Ansible Phase: Menggunakan dynamic inventory yang dihasilkan Terraform, Ansible terhubung via SSH untuk mengeksekusi playbook secara idempotent, memastikan state akhir server sesuai dengan spesifikasi yang diinginkan.

3. Perbandingan Komparatif / Analisis Pendekatan

Parameter Analisis Terraform (Infrastructure Provisioning) Ansible (Configuration Management) Bash Scripting / Custom Tooling
Paradigma Deklaratif (Declarative State) Deklaratif / Idempotent Imperatif (Imperative Procedural)
State Management Menyimpan state di backend terpusat Stateless (Mengecek kondisi real-time target) Tidak ada state management bawaan
Penggunaan Ideal Membuat VPC, VM, DB, S3, DNS, CDN Instalasi paket, setting daemon, app deploy Tugas skrip sekali jalan yang sangat spesifik
Konsumsi CPU/RAM Ringan (CLI Go binary) Ringan (Python-based agentless via SSH) Sangat ringan namun tidak aman untuk skala besar
Trade-off Kurang optimal untuk manajemen file konfigurasi kompleks di dalam OS Kurang optimal untuk mengatur dependensi resource cloud global Sangat sulit di-maintain, rentan error saat kegagalan parsial

4. Prasyarat Sistem & Persiapan Lingkungan

Sebelum memulai implementasi, pastikan tools berikut terpasang pada mesin kontroler (CI/CD runner atau local admin workstation):

  • Terraform: v1.5.0 atau lebih tinggi.
  • Ansible: v2.14+ dengan Python 3.10+.
  • Cloud CLI: AWS CLI / GCP CLI yang telah dikonfigurasi dengan kredensial akses yang memadai.
  • SSH Key Pair: Kunci privat/publik RSA 4096-bit untuk autentikasi server.

Verifikasi instalasi dasar:

terraform --version
ansible --version
aws sts get-caller-identity

5. Panduan Implementasi Langkah demi Langkah

Struktur Direktori Proyek

infra-automation/
├── terraform/
│   ├── main.tf
│   ├── variables.tf
│   ├── outputs.tf
│   └── backend.tf
└── ansible/
    ├── inventory.ini
    ├── playbook.yml
    └── roles/
        └── web_stack/
            ├── tasks/
            │   └── main.yml
            └── templates/
                └── nginx.conf.j2

1. Terraform Configuration (terraform/main.tf)

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

provider "aws" {
  region = var.aws_region
}

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

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

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

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

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

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

  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 {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_instance" "web_server" {
  ami                    = "ami-0c7217cdde317cfec" # Ubuntu 22.04 LTS
  instance_type          = "t3.medium"
  subnet_id              = aws_subnet.public.id
  vpc_security_group_ids = [aws_security_group.web_sg.id]
  key_name               = var.ssh_key_name

  tags = {
    Name = "production-web-node"
  }
}

output "server_public_ip" {
  value = aws_instance.web_server.public_ip
}

2. Ansible Playbook (ansible/playbook.yml)

---
- name: Provision Web and Infrastructure Stack
  hosts: webservers
  become: true
  vars:
    domain_name: "example.com"
    app_user: "deployer"
  tasks:
    - name: Update apt cache and install core packages
      apt:
        update_cache: yes
        cache_valid_time: 3600
        name:
          - curl
          - git
          - ufw
          - fail2ban
          - nginx
          - redis-server
          - supervisor
        state: present

    - name: Configure UFW firewall rules
      ufw:
        rule: allow
        port: "{{ item }}"
        proto: tcp
      loop:
        - "22"
        - "80"
        - "443"

    - name: Enable UFW
      ufw:
        state: enabled
        policy: deny

    - name: Ensure Redis is running and enabled on boot
      systemd:
        name: redis-server
        state: started
        enabled: yes

    - name: Deploy Nginx Global Configuration
      template:
        src: "templates/nginx.conf.j2"
        dest: "/etc/nginx/sites-available/default"
        owner: root
        group: root
        mode: '0644'
      notify: Restart Nginx

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

6. Bedah Kode & Penjelasan Detail Baris Kunci

  • enable_dns_hostnames = true (Terraform): Memastikan instance EC2 yang dibuat di dalam VPC mendapatkan DNS hostname publik yang valid, krusial bagi integrasi layanan pihak ketiga dan resolusi Cloudflare.
  • cache_valid_time: 3600 (Ansible): Mencegah Ansible melakukan pembaruan indeks apt secara terus-menerus pada setiap tugas, menghemat waktu eksekusi playbook dan mencegah pembatasan rate dari mirror repositori.
  • notify: Restart Nginx (Ansible Handler): Memastikan Nginx hanya direstart jika berkas konfigurasi template mengalami perubahan (changed), meminimalkan risiko gangguan koneksi yang tidak perlu.

7. Skenario Produksi & Studi Kasus Dunia Nyata

[!IMPORTANT] Pada lingkungan produksi dengan beban tinggi (high concurrency), pengelolaan state Terraform wajib disimpan di Remote Backend (misalnya AWS S3 dengan DynamoDB State Locking) guna mencegah korupsi state saat dikerjakan oleh beberapa engineer atau CI/CD pipeline secara bersamaan.

Untuk menangani traffic tinggi, arsitektur dikembangkan dengan menambahkan Load Balancer (ALB) di depan auto-scaling group instance Nginx + PHP-FPM/Node.js, serta memanfaatkan Cloudflare sebagai Edge Caching dan WAF untuk menyaring serangan DDoS layer 7 sebelum mencapai server asal (origin).


8. Common Pitfalls, Anti-Patterns & Solusi

  • Anti-Pattern 1: Menyimpan Secret di dalam Git Repository. Solusi: Gunakan Terraform Variables yang dienkripsi menggunakan HashiCorp Vault, AWS SSM Parameter Store, atau Ansible Vault.
  • Anti-Pattern 2: Hardcoding IP Address pada Ansible Inventory. Solusi: Gunakan Terraform outputs yang dikirimkan secara otomatis ke berkas dynamic inventory Ansible menggunakan skrip eksternal atau plugin AWS EC2 inventory.
  • Anti-Pattern 3: Mengabaikan Idempotency. Solusi: Pastikan setiap task Ansible menggunakan modul native (seperti ansible.builtin.template, ansible.builtin.systemd) alih-alih menjalankan perintah shell mentah (command: sed -i ...).

9. Benchmark, Metrik Kinerja & Tuning Performa

Pengujian performa infrastruktur dilakukan menggunakan tool k6 untuk menguji ketahanan web server terhadap lonjakan HTTP requests.

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

export const options = {
  stages: [
    { duration: '30s', target: 100 },
    { duration: '1m', target: 500 },
    { duration: '30s', target: 0 },
  ],
};

export default function () {
  const res = http.get('http://example.com');
  check(res, { 'status was 200': (r) => r.status === 200 });
  sleep(1);
}

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

net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 8192
fs.file-max = 2097152

Terapkan perubahan dengan perintah sudo sysctl -p untuk menghindari error Too many open files pada beban tinggi.


10. Checklist Penerapan Produksi & Kesimpulan

  • Remote state Terraform terenkripsi dan aktif dengan state locking.
  • Seluruh SSH akses menggunakan kunci publik, password authentication dinonaktifkan.
  • Fail2ban terkonfigurasi untuk memblokir brute-force pada port SSH dan Nginx.
  • Skrip Ansible terbukti idempotent pada uji coba berulang (dry-run).
  • Backup otomatis database dan volume penyimpanan dijadwalkan secara rutin.

Penerapan otomatisasi infrastruktur menggunakan Terraform dan Ansible secara konsisten memastikan keandalan sistem, memangkas waktu rilis, dan mengeliminasi human error di level produksi.

🏷️ Tags: #Nginx #Devops #Terraform #Ansible #Infrastructure As Code