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

Automasi Infrastruktur Skala Besar Menggunakan Terraform dan Ansible di AWS

⏱️ 18 menit baca β€’ πŸ“… 13 Oct 2026 β€’ πŸ‘οΈ 1 views
Automasi Infrastruktur Skala Besar Menggunakan Terraform dan Ansible di AWS

Panduan Lengkap: Automasi Infrastruktur Skala Besar Menggunakan Terraform dan Ansible di AWS

1. Konteks Industri & Analisis Akar Masalah

Dalam lanskap arsitektur web modern, skalabilitas, ketahanan sistem (high-availability), dan kecepatan pemulihan (disaster recovery) bukan lagi sekadar nilai tambah, melainkan syarat mutlak. Secara historis, pengelolaan server dilakukan secara manual atau menggunakan scripting ad-hoc. Pendekatan ini melahirkan fenomena klasik yang dikenal sebagai Configuration Drift dan Snowflake Serversβ€”di mana setiap mesin memiliki karakteristik unik yang tidak terdokumentasi, membuat proses penskalaan, migrasi, dan pemecahan masalah menjadi mimpi buruk bagi tim Infrastructure and Operations (InfraOps).

Masalah ini berakar pada inkonsistensi lingkungan. Ketika sebuah aplikasi web berskala besar yang ditenagai oleh tumpukan teknologi modernβ€”seperti frontend berbasis framework JavaScript, backend Go/Node.js/PHP-FPM, web server Nginx, database cluster MySQL/MariaDB, serta lapisan caching Redisβ€”dideploy secara manual ke AWS EC2, risiko kegagalan manusia sangat tinggi. Kesalahan konfigurasi pada security groups, pengaturan file sistem, izin direktori, hingga variabel lingkungan (environment variables) dapat menyebabkan kebocoran data, kerentanan WAF (Web Application Firewall), atau kegagalan integrasi DNS (Record A, MX, SPF, DKIM, DMARC).

Perbandingan: Sebelum vs. Sesudah Penerapan Automasi

  • Sebelum Automasi (Manual / Ad-hoc):

    • Deployment Time: Membutuhkan waktu berhari-hari hingga berminggu-minggu untuk menyiapkan lingkungan baru.
    • Reproducibility: Rendah. Hampir tidak mungkin mereplikasi lingkungan staging agar 100% identik dengan production.
    • Auditing & Compliance: Sangat sulit dilacak. Perubahan konfigurasi dilakukan langsung melalui SSH (SSH-driven development).
    • Downtime: Tinggi, terutama saat terjadi kegagalan infrastruktur karena pemulihan bersifat manual.
  • Sesudah Automasi (Terraform + Ansible):

    • Deployment Time: Infrastruktur lengkap beserta konfigurasi layanannya siap dalam hitungan menit (mendekati zero-touch provisioning).
    • Reproducibility: Sempurna. Seluruh infrastruktur didefinisikan sebagai kode (Infrastructure as Code / IaC).
    • Auditing & Compliance: Terpusat. Perubahan kode melalui pull request di Git menyediakan jejak audit yang transparan.
    • Downtime: Minimal. Menerapkan prinsip Immutable Infrastructure di mana server yang rusak tidak diperbaiki, melainkan dihancurkan dan diganti dengan instans baru secara otomatis.

2. Konsep Inti & Deep Dive Arsitektur

Untuk membangun pipeline automasi yang andal di AWS, kita membagi tanggung jawab secara tegas antara Terraform dan Ansible berdasarkan filosofi fungsionalitas mereka:

  1. Terraform (Provisioning & Orkestrasi Cloud): Bertanggung jawab atas pengelolaan sumber daya cloud tingkat infrastruktur (IaaS). Terraform memetakan seluruh komponen AWS seperti VPC, Subnets, Internet Gateways, Route Tables, Security Groups, EC2 Instances, S3 Buckets, RDS, dan Elastic Load Balancers (ELB).
  2. Ansible (Configuration Management & Software Deployment): Bertanggung jawab atas pengelolaan bagian dalam sistem operasi (OS-level configuration). Setelah Terraform selesai memprovisi instans EC2, Ansible mengambil alih untuk memasang paket perangkat lunak (Nginx, PHP-FPM, Redis, Postfix), mengatur konfigurasi web server, menyalin file aset, dan menjalankan skrip inisialisasi.

Alur Kerja Eksekusi (Architecture Flow Chart)

+-----------------------------------------------------------------------+
|                        Developer / Git Repository                     |
+-----------------------------------------------------------------------+
                                    |
                                    v
+-----------------------------------------------------------------------+
|                    Terraform (Provisioning Phase)                     | 
|  - AWS VPC, Subnets, Security Groups, IAM Roles                       | 
|  - EC2 Instances Deployment                                           | 
+-----------------------------------------------------------------------+
                                    |
                                    | (Outputs: Public/Private IPs)
                                    v
+-----------------------------------------------------------------------+
|                  Dynamic Inventory Generation                         | 
+-----------------------------------------------------------------------+
                                    |
                                    v
+-----------------------------------------------------------------------+
|                    Ansible (Configuration Phase)                      | 
|  - Connect via SSH (SSH Keys provisioned by Terraform)                | 
|  - Install Nginx, PHP-FPM, Node.js, Redis, Certbot                    | 
|  - Apply Hardening & Security (Fail2ban, UFW)                         | 
+-----------------------------------------------------------------------+
                                    |
                                    v
+-----------------------------------------------------------------------+
|                       Production-Ready System                         | 
+-----------------------------------------------------------------------+

[!IMPORTANT] Jangan pernah menggunakan Terraform untuk manajemen file konfigurasi aplikasi skala mikro secara masif, dan jangan pernah menggunakan Ansible untuk membuat VPC atau RDS. Gunakan spesialisasi alat sesuai peruntukannya (Terraform for Infrastructure, Ansible for Configuration).


3. Perbandingan Komparatif / Analisis Pendekatan

Dalam membangun arsitektur automasi, terdapat beberapa pilihan pendekatan alat bantu. Tabel berikut membedah perbandingan antara kombinasi Terraform + Ansible melawan alternatif lain.

Parameter Komparasi Terraform + Ansible (Direkomendasikan) CloudFormation + AWS Systems Manager Pulumi + Chef/Puppet
Cakupan Cloud Multi-Cloud (AWS, GCP, Azure, Cloudflare) Eksklusif AWS Multi-Cloud (Mendukung bahasa umum seperti TS/Python)
Kurva Pembelajaran Moderat (HCL untuk Terraform, YAML untuk Ansible) Curam (JSON/YAML khusus AWS yang sangat verbose) Tinggi (Membutuhkan penguasaan bahasa pemrograman)
State Management Terraform State (Lokal / S3 + DynamoDB) Dikelola penuh oleh AWS CloudFormation Pulumi Service / S3 Backend
Manajemen Konfigurasi Sangat kuat dan modular melalui Ansible Roles Terbatas pada AWS SSM / User Data scripts Kompleks, bergantung pada integrasi pihak ketiga
Dampak Sumber Daya Efisien, menggunakan memori dan CPU minimal saat eksekusi Dikelola oleh API AWS, tanpa beban sumber daya lokal Memerlukan runtime bahasa (Node.js/Python) saat eksekusi

4. Prasyarat Sistem & Persiapan Lingkungan

Sebelum memulai implementasi, pastikan lingkungan kerja lokal atau server CI/CD runner Anda memiliki perangkat lunak berikut:

  1. Terraform CLI (Versi >= 1.5.0)
  2. Ansible (Versi >= 2.14)
  3. AWS CLI v2 (Telah dikonfigurasi dengan kredensial IAM yang memiliki hak akses penuh ke EC2, VPC, IAM, S3)
  4. SSH Client & Key Pair (Kunci privat untuk mengakses instans AWS)

Verifikasi instalasi dengan perintah berikut:

terraform -version
ansible --version
aws --version

Pastikan variabel lingkungan AWS telah terekspor dengan benar:

export AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
export AWS_REGION="us-east-1"

5. Panduan Implementasi Langkah demi Langkah

Berikut adalah implementasi nyata untuk membangun infrastruktur web high-availability di AWS menggunakan Terraform untuk provisi dan Ansible untuk konfigurasi server web (Nginx + PHP-FPM + Redis).

Struktur Direktori Proyek

infra-automation/
β”œβ”€β”€ terraform/
β”‚   β”œβ”€β”€ main.tf
β”‚   β”œβ”€β”€ variables.tf
β”‚   β”œβ”€β”€ outputs.tf
β”‚   └── terraform.tfvars
└── ansible/
    β”œβ”€β”€ inventory.ini
    β”œβ”€β”€ playbook.yml
    └── roles/
        └── webserver/
            β”œβ”€β”€ tasks/
            β”‚   └── main.yml
            └── templates/
                └── nginx.conf.j2

Tahap 1: Konfigurasi Terraform (terraform/main.tf)

File ini mendefinisikan infrastruktur dasar AWS termasuk VPC, Subnet, Security Group, dan instans EC2.

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

provider "aws" {
  region = var.aws_region
}

# Membuahkan VPC Sederhana
resource "aws_vpc" "main" {
  cidr_block           = "10.0.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.0.1.0/24"
  map_public_ip_on_launch = true

  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
}

# Security Group untuk Akses Web & SSH
resource "aws_security_group" "web_sg" {
  name        = "prod-web-sg"
  description = "Allow HTTP, HTTPS, and SSH"
  vpc_id      = aws_vpc.main.id

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

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

  ingress {
    description = "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"]
  }

  tags = {
    Name = "prod-web-sg"
  }
}

# Key Pair untuk SSH
resource "aws_key_pair" "deployer" {
  key_name   = "prod-deployer-key"
  public_key = file("~/.ssh/id_rsa.pub")
}

# AWS EC2 Instance
resource "aws_instance" "web_server" {
  ami                    = var.ami_id
  instance_type          = var.instance_type
  subnet_id              = aws_subnet.public.id
  vpc_security_group_ids = [aws_security_group.web_sg.id]
  key_name               = aws_key_pair.deployer.key_name

  tags = {
    Name = "prod-web-instance"
  }
}

Tahap 2: Variabel dan Output Terraform (terraform/variables.tf & outputs.tf)

# variables.tf
variable "aws_region" {
  type    = string
  default = "us-east-1"
}

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

variable "ami_id" {
  type        = string
  description = "Ubuntu 22.04 LTS AMI ID"
  default     = "ami-0fc5d935ebf8bc3bc"
}
# outputs.tf
output "web_instance_ip" {
  value       = aws_instance.web_server.public_ip
  description = "Public IP address of the web server instance"
}

Tahap 3: Konfigurasi Ansible Inventory (ansible/inventory.ini)

Gunakan IP publik yang dihasilkan oleh output Terraform untuk mengisi inventory Ansible.

[webservers]
<GANTI_DENGAN_IP_PUBLIK_TERRAFORM> ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa

Tahap 4: Ansible Playbook & Role (ansible/playbook.yml)

---
- name: Provision and Configure Web Server Stack
  hosts: webservers
  become: yes
  roles:
    - webserver

Definisikan tugas pada direktori ansible/roles/webserver/tasks/main.yml:

---
- name: Update apt cache
  apt:
    update_cache: yes
    cache_valid_time: 3600

- name: Install Nginx, PHP-FPM, and Redis
  apt:
    name:
      - nginx
      - php8.1-fpm
      - php8.1-cli
      - php8.1-redis
      - redis-server
      - curl
    state: present

- name: Ensure Nginx and PHP-FPM are running and enabled
  systemd:
    name: "{{ item }}"
    state: started
    enabled: yes
  loop:
    - nginx
    - php8.1-fpm
    - redis-server

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

- name: Create web root directory
  file:
    path: /var/www/html
    state: directory
    owner: www-data
    group: www-data
    mode: '0755'

- name: Deploy a basic index.php
  copy:
    content: "<?php echo 'Infrastructure Automation Successful with Terraform and Ansible! PHP Version: ' . phpversion(); ?>"
    dest: /var/www/html/index.php
    owner: www-data
    group: www-data
    mode: '0644'

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

Dan template Nginx di ansible/roles/webserver/templates/nginx.conf.j2:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;
    index index.php index.html index.htm index.nginx-debian.html;

    server_name _;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
    }

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

6. Bedah Kode & Penjelasan Detail Baris Kunci

  1. enable_dns_hostnames = true pada Terraform VPC: Konfigurasi ini krusial agar instans EC2 mendapatkan nama DNS publik otomatis yang valid. Jika diset false, komunikasi internal antar layanan berbasis hostname AWS akan gagal.
  2. map_public_ip_on_launch = true pada Subnet: Memastikan instans yang dibuat langsung mendapatkan IP publik tanpa harus mengonfigurasi Elastic IP manual secara terpisah, mempercepat proses bootstrap Ansible.
  3. cache_valid_time: 3600 pada Ansible Apt Module: Mencegah Ansible melakukan pembaruan cache apt berulang kali jika tugas dijalankan dalam rentang waktu kurang dari 1 jam, menghemat waktu eksekusi playbook.
  4. fastcgi_pass unix:/var/run/php/php8.1-fpm.sock pada Template Nginx: Menghubungkan Nginx dan PHP-FPM melalui Unix Socket ketimbang TCP Port lokal. Ini jauh lebih cepat dan aman untuk komunikasi intra-server karena memangkas overhead jaringan TCP/IP.

7. Skenario Produksi & Studi Kasus Dunia Nyata

Pada lingkungan produksi skala besar, arsitektur di atas perlu ditingkatkan menjadi Auto Scaling Architecture. Instans tunggal digantikan dengan kerangka kerja Load Balancer dan Auto Scaling Group (ASG).

  • Load Balancer (AWS ALB): Menerima traffic masuk di port 80/443 dan mendistribusikannya ke sekumpulan instance EC2 di private subnet.
  • Dynamic Inventory Ansible: Alih-alih menggunakan file inventory.ini statis, gunakan plugin AWS EC2 dynamic inventory (aws_ec2.yml) agar Ansible dapat secara otomatis mendeteksi server baru yang ditambahkan oleh Terraform atau AWS Auto Scaling.

Contoh konfigurasi dynamic inventory aws_ec2.yaml:

---
plugin: amazon.aws.aws_ec2
regions:
  - us-east-1
filters:
  tag:Name: prod-web-instance
  instance-state-name: running
keyed_groups:
  - key: tags.Name
    prefix: tag

8. Common Pitfalls, Anti-Patterns & Solusi

  • Anti-Pattern 1: Menyimpan Terraform State secara Lokal.
    • Dampak: Jika file terraform.tfstate hilang atau rusak pada mesin lokal, tim akan kehilangan pemetaan infrastruktur cloud.
    • Solusi: Selalu gunakan remote backend terpusat menggunakan AWS S3 dengan enkripsi aktif dan DynamoDB untuk mekanisme State Locking.
  • Anti-Pattern 2: Menjalankan Perintah ansible Tanpa Idempotency.
    • Dampak: Skrip shell kustom di dalam Ansible yang tidak idempotent akan merusak konfigurasi server setiap kali playbook dijalankan kembali.
    • Solusi: Selalu gunakan modul bawaan Ansible (apt, template, systemd, file) ketimbang modul shell atau command mentah.
  • Pitfall 3: Timeouts pada SSH Connection saat EC2 Baru Booting.
    • Solusi: Gunakan modul wait_for_connection di Ansible sebelum menjalankan tugas konfigurasi utama.

9. Benchmark, Metrik Kinerja & Tuning Performa

Setelah infrastruktur berhasil diotomatisasi, lakukan pengujian beban (load testing) menggunakan perangkat k6 atau wrk untuk memastikan tumpukan web server (Nginx + PHP-FPM) mampu menangani traffic tinggi.

Skrip pengujian beban k6 sederhana (load-test.js):

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

export const options = {
  stages: [
    { duration: '30s', target: 50 },  // Ramp-up hingga 50 pengguna
    { duration: '1m', target: 200 },  // Pertahankan 200 pengguna
    { duration: '10s', target: 0 },   // Ramp-down
  ],
};

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

Tuning Parameter Lanjutan (Nginx & PHP-FPM):

  • Tingkatkan jumlah worker processes Nginx sesuai dengan jumlah inti CPU (worker_processes auto;).
  • Atur parameter pm.max_children, pm.start_servers, dan pm.min_spare_servers pada /etc/php/8.1/fpm/pool.d/www.conf berdasarkan kapasitas RAM instans EC2 untuk menghindari kehabisan memori (OOM Killer).

10. Checklist Penerapan Produksi & Kesimpulan

Sebelum meluncurkan infrastruktur ini ke lingkungan production, pastikan checklist berikut terpenuhi:

  • Terraform State diamankan menggunakan S3 Backend + DynamoDB State Locking.
  • Kunci SSH pribadi tidak pernah disimpan di dalam repositori Git publik.
  • Aturan Security Groups AWS dibatasi seketat mungkin (prinsip least privilege).
  • Sertifikat SSL/TLS (misal: Let's Encrypt dengan Certbot) telah dikonfigurasi pada Nginx.
  • Pemantauan log dan metrik (CloudWatch atau Prometheus/Grafana) telah diintegrasikan.
  • Ansible Playbook diuji pada lingkungan staging yang identik.

Dengan memadukan ketangguhan Terraform dalam provisi sumber daya cloud dan fleksibilitas Ansible dalam konfigurasi sistem operasi, organisasi Anda kini memiliki pipeline infrastruktur yang sepenuhnya dapat direproduksi (reproducible), aman, dan siap menghadapi skala beban kerja enterprise tingkat tinggi.

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