Automating Multi-Cloud Infrastructure with Terraform and Ansible
Automating Multi-Cloud Infrastructure with Terraform and Ansible
1. Konteks Industri & Analisis Akar Masalah
Dalam lanskap arsitektur web modern, skalabilitas, ketahanan bencana (disaster recovery), dan fleksibilitas biaya menjadi pilar utama penentuan kesuksesan platform digital. Perusahaan enterprise kini semakin meninggalkan pendekatan single-vendor lock-in (mengandalkan satu penyedia cloud saja seperti AWS atau Google Cloud Platform) dan beralih ke strategi multi-cloud atau hybrid cloud. Namun, pengelolaan infrastruktur yang terdistribusi secara manual atau menggunakan skrip ad-hoc shell terbukti mendatangkan malapetaka operasional.
Bottleneck terbesar di dunia nyata terletak pada ketidakkonsistenan konfigurasi lingkungan (configuration drift), kompleksitas pengelolaan kredensial rahasia secara manual, serta proses provisioning yang memakan waktu berhari-hari. Bayangkan sebuah skenario di mana tim web engineering harus meluncurkan klaster aplikasi Node.js berkinerja tinggi di AWS EC2 untuk frontend, sementara basis data utama MySQL/MariaDB dan caching layer Redis dijalankan di DigitalOcean atau Google Cloud Platform untuk optimalisasi latensi regional.
Sebelum adopsi Infrastructure as Code (IaC) dan Configuration Management otomatis, perubahan aturan firewall atau pembaruan konfigurasi PHP-FPM di 50 instance server harus dilakukan melalui SSH satu per satu. Hal ini tidak hanya memicu human error, tetapi juga membuka celah keamanan yang masif akibat perbedaan aturan security group dan hilangnya jejak audit (audit trail).
Sesudah penerapan otomatisasi terpadu menggunakan kombinasi Terraform dan Ansible:
- Sebelum: Provisioning server memakan waktu 3-5 hari kerja, konfigurasi server rentan drift, dan proses rollback saat terjadi kegagalan sistem bersifat destruktif dan manual.
- Sesudah: Seluruh siklus hidup infrastruktur dari pembuatan Virtual Private Cloud (VPC), pengaturan DNS (Record A, MX, SPF, DKIM, DMARC), hingga instalasi Web Server (Nginx/Caddy), runtime Go/Node.js, dan konfigurasi WAF (Fail2ban) dapat diselesaikan dalam waktu kurang dari 10 menit secara deklaratif dan idempoten.
2. Konsep Inti & Deep Dive Arsitektur
Arsitektur otomatisasi multi-cloud yang tangguh membagi tugas secara tegas berdasarkan prinsip Separation of Concerns:
- Terraform: Bertindak sebagai Provisioner (fase Day-0). Ia mendefinisikan Infrastructure as Code (IaC) untuk membuat sumber daya komputasi, jaringan, penyimpanan (S3/MinIO), dan manajemen DNS secara deklaratif.
- Ansible: Bertindak sebagai Configuration Management & Orchestrator (fase Day-1 dan Day-2). Ia mengambil alih setelah server fisik atau virtual terbentuk, melakukan provisioning perangkat lunak, konfigurasi layanan web, manajemen user, pengetatan keamanan SSH, hingga deployment aplikasi.
+--------------------------------------------------------------------------+
| Developer / CI/CD Pipeline |
+--------------------------------------------------------------------------+
|
v
+--------------------------------------------------------------------------+
| Terraform (Modular State Management) |
| - Creates VPC, Subnets, Security Groups, EC2 / Droplets, S3 / MinIO |
+--------------------------------------------------------------------------+
|
v (Generates Dynamic Inventory)
+--------------------------------------------------------------------------+
| Ansible Playbook Provisioning & Orchestration |
| - Hardening OS, Nginx/Caddy, PHP-FPM / Node.js / Go, Fail2ban, SSL |
+--------------------------------------------------------------------------+
|
v
+--------------------------------------------------------------------------+
| Production-Ready Multi-Cloud Infrastructure |
+--------------------------------------------------------------------------+
Alur eksekusi data berjalan secara sekuensial namun terintegrasi. Terraform mengeksekusi plan terhadap API cloud provider (AWS, GCP, DigitalOcean), menyimpan state secara terenkripsi di remote backend (misalnya S3 dengan locking DynamoDB), lalu mengeluarkan output berupa alamat IP publik dan privat yang secara otomatis diinjeksikan ke dalam Ansible Dynamic Inventory.
3. Perbandingan Komparatif / Analisis Pendekatan
Dalam membangun infrastruktur web berskala enterprise, pemilihan tool dan pendekatan arsitektur menentukan efisiensi biaya infrastruktur dan Time-to-Market.
| Parameter Perbandingan | Manual Provisioning & Shell Script | Terraform Only (Cloud-Init) | Terraform + Ansible (Hybrid IaC) |
|---|---|---|---|
| Idempotensi | Rendah (Sering gagal/duplikasi) | Tinggi (Infrastruktur), Rendah (OS Config) | Sangat Tinggi (Infrastruktur & OS) |
| Kompleksitas Multi-Cloud | Sangat Tinggi & Berisiko | Baik untuk Cloud Resources, Buruk untuk OS | Optimal (Terraform untuk Cloud, Ansible untuk OS) |
| Kecepatan Rollback | Lambat (> 4 jam) | Cepat (15 menit untuk Cloud) | Cepat & Aman (Infrastruktur + Konfigurasi) |
| Jejak Audit / State | Tidak ada | Terpusat (Terraform State) | Terpusat + Logging Ansible Playbook |
| Penggunaan CPU/RAM Latency | Boros akibat overhead manual | Efisien | Efisien dengan manajemen task paralel |
[!IMPORTANT] Jangan pernah menggunakan Terraform untuk melakukan manajemen konfigurasi perangkat lunak yang kompleks (seperti compile Nginx dari source atau setup kompleks database cluster) karena state locking Terraform tidak didesain untuk pelacakan perubahan level paket OS yang tinggi frekuensinya.
4. Prasyarat Sistem & Persiapan Lingkungan
Sebelum mengeksekusi konfigurasi, pastikan workstation atau CI/CD runner Anda memiliki dependensi versi berikut:
- Terraform: Versi
>= 1.6.0 - Ansible: Versi
>= 2.15.0 - AWS CLI / Doctl: Terkonfigurasi dengan kunci API yang memiliki izin Administrator atau hak akses penuh ke layanan komputasi dan jaringan.
- Struktur Direktori Proyek:
multicloud-infra/
├── terraform/
│ ├── main.tf
│ ├── variables.tf
│ ├── outputs.tf
│ └── backend.tf
├── ansible/
│ ├── inventory/
│ │ └── dynamic_inventory.yaml
│ ├── playbooks/
│ │ └── site.yaml
│ └── roles/
│ ├── common/
│ ├── webserver/
│ └── database/
└── scripts/
└── deploy.sh
Verifikasi instalasi awal dengan menjalankan perintah terminal:
terraform version
ansible --version
5. Panduan Implementasi Langkah demi Langkah
Langkah 1: Konfigurasi Modular Terraform State Management
Buat file backend untuk menyimpan state Terraform secara aman dan terdistribusi di AWS S3 dengan dukungan DynamoDB state locking.
# terraform/backend.tf
terraform {
required_version = ">= 1.6.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
digitalocean = {
source = "digitalocean/digitalocean"
version = "~> 2.30"
}
}
backend "s3" {
bucket = "enterprise-terraform-state-bucket-production"
key = "multi-cloud/infrastructure.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-state-locks"
encrypt = true
}
}
provider "aws" {
region = "us-east-1"
}
provider "digitalocean" {
token = var.do_token
}
Definisikan sumber daya utama yang mencakup instans web pada AWS EC2 dan basis data di DigitalOcean Droplet.
# terraform/main.tf
variable "do_token" {
type = string
sensitive = true
}
resource "aws_vpc" "main_vpc" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "Production-AWS-VPC"
Environment = "Production"
}
}
resource "aws_subnet" "public_subnet" {
vpc_id = aws_vpc.main_vpc.id
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
availability_zone = "us-east-1a"
tags = {
Name = "Production-Public-Subnet"
}
}
resource "aws_security_group" "web_sg" {
name = "web-server-sg"
description = "Allow HTTP, HTTPS, and SSH"
vpc_id = aws_vpc.main_vpc.id
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"]
}
ingress {
description = "Allow SSH"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # Ganti dengan IP bastion host di produksi
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "web_node" {
ami = "ami-0c7217cdde317cfec" # Ubuntu 22.04 LTS
instance_type = "t3.medium"
subnet_id = aws_subnet.public_subnet.id
vpc_security_group_ids = [aws_security_group.web_sg.id]
key_name = "production-deployer-key"
tags = {
Name = "WebNode-AWS-Prod"
Role = "webserver"
Environment = "production"
}
}
resource "digitalocean_droplet" "db_node" {
image = "ubuntu-22-04-x64"
name = "db-node-do-prod"
region = "sgp1"
size = "s-2vcpu-4gb"
ssh_keys = [var.do_ssh_key_id]
tags = ["database", "production"]
}
output "web_node_ip" {
value = aws_instance.web_node.public_ip
}
output "db_node_ip" {
value = digitalocean_droplet.db_node.ipv4_address
}
Langkah 2: Ansible Playbook untuk Konfigurasi & Hardening Server
Buat struktur Ansible Playbook utama untuk mengonfigurasi node web server dengan Nginx, PHP-FPM 8.2, dan Fail2ban untuk perlindungan WAF dasar.
# ansible/playbooks/site.yaml
---
- name: Configure Production Web Infrastructure
hosts: webserver
become: true
vars:
php_version: "8.2"
roles:
- role: common
- role: webserver
- name: Configure Production Database Infrastructure
hosts: database
become: true
roles:
- role: common
- role: database
Buat Ansible Role untuk webserver (ansible/roles/webserver/tasks/main.yaml):
---
- name: Add PPA for PHP repository
apt_repository:
repo: "ppa:ondrej/php"
state: present
- name: Install Nginx, PHP-FPM, and Security Packages
apt:
name:
- nginx
- php8.2-fpm
- php8.2-mysql
- php8.2-redis
- php8.2-mbstring
- php8.2-xml
- fail2ban
- ufw
state: present
update_cache: yes
- name: Configure Nginx Virtual Host for Enterprise Web App
template:
src: nginx_vhost.j2
dest: /etc/nginx/sites-available/default
owner: root
group: root
mode: '0644'
notify: Restart Nginx
- name: Enable and start Fail2ban service
systemd:
name: fail2ban
enabled: true
state: started
- name: Configure UFW Firewall Rules
ufw:
rule: allow
port: "{{ item }}"
proto: tcp
loop:
- 22
- 80
- 443
- name: Enable UFW Firewall
ufw:
state: enabled
policy: deny
handlers:
- name: Restart Nginx
systemd:
name: nginx
state: restarted
enabled: true
Template Nginx (ansible/roles/webserver/templates/nginx_vhost.j2):
server {
listen 80;
server_name example.com www.example.com;
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/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /.ht {
deny all;
}
}
6. Bedah Kode & Penjelasan Detail Baris Kunci
- Terraform Backend S3 & DynamoDB Locking (
backend.tf):- Parameter
encrypt = truememastikan bahwa data state yang memuat konfigurasi sensitif terenkripsi secara at-rest menggunakan AWS KMS. Penggunaandynamodb_tablemencegah race condition jika dua engineer atau CI/CD pipeline mencoba melakukan apply secara bersamaan.
- Parameter
- Security Group AWS (
main.tf):- Membuka port standar web (80, 443) untuk publik dan membatasi port SSH (22). Di lingkungan enterprise tingkat lanjut, akses port 22 wajib dibatasi hanya melalui IP VPN perusahaan atau AWS Systems Manager Session Manager tanpa membuka ingress port sama sekali.
- Ansible Idempotent Package Installation (
webserver/tasks/main.yaml):- Penggunaan modul
aptdenganupdate_cache: yesmemastikan paket berada pada versi mutakhir yang aman dari kerentanan CVE terbaru tanpa memicu instalasi ulang jika paket sudah terpasang.
- Penggunaan modul
- Nginx Security Header Headers (
nginx_vhost.j2):- Penambahan
X-Frame-Options,X-Content-Type-Options, danContent-Security-Policymelindungi aplikasi web dari serangan Clickjacking, MIME-type sniffing, dan Cross-Site Scripting (XSS).
- Penambahan
7. Skenario Produksi & Studi Kasus Dunia Nyata
[!TIP] Untuk menangani lonjakan traffic jutaan requests per detik (High Concurrency), integrasikan Terraform dan Ansible untuk memprovisikan Auto Scaling Group (ASG) di AWS di belakang Cloudflare Enterprise CDN, serta memisahkan backend API berbasis Node.js/Go dengan database sharding MariaDB.
Dalam studi kasus implementasi platform e-commerce saat flash sale, lonjakan traffic dipetakan melalui skenario berikut:
- Terraform menduplikasi instans AWS EC2 menggunakan Launch Template dan Application Load Balancer (ALB).
- Ansible secara otomatis memperbarui upstream configuration Nginx dan melakukan rolling restart pada layanan PHP-FPM / Node.js tanpa downtime (zero-downtime deployment).
- Cache Redis dikonfigurasi secara klaster terdistribusi melalui Ansible untuk mengurangi beban query langsung ke basis data utama.
8. Common Pitfalls, Anti-Patterns & Solusi
- Anti-Pattern 1: Menyimpan Secret di dalam File Terraform atau Ansible Playbook.
- Solusi: Selalu gunakan Terraform
sensitive = true, Ansible Vault, atau integrasikan dengan HashiCorp Vault / AWS Secrets Manager.
- Solusi: Selalu gunakan Terraform
- Anti-Pattern 2: Tidak Mengunci Versi Provider Terraform.
- Solusi: Gunakan operator pembatas versi
~> 5.0pada blokrequired_providersuntuk menghindari breaking changes dari pembaruan mayor otomatis.
- Solusi: Gunakan operator pembatas versi
- Anti-Pattern 3: Menjalankan Ansible Tanpa Idempotensi (Menggunakan Command Shell Bebas).
- Solusi: Manfaatkan modul bawaan Ansible seperti
template,file,apt, dansystemdyang secara native mendesain eksekusi yang aman dijalankan berulang kali.
- Solusi: Manfaatkan modul bawaan Ansible seperti
9. Benchmark, Metrik Kinerja & Tuning Performa
Lakukan pengujian beban (load testing) pada infrastruktur web yang telah diprovisikan menggunakan tool wrk atau k6 untuk mengukur latensi dan throughput server.
Contoh perintah pengujian beban menggunakan wrk:
wrk -t12 -c400 -d30s http://<AWS_WEB_NODE_IP>/
Tuning Parameter Linux Kernel (/etc/sysctl.conf) via Ansible:
Untuk memaksimalkan kapasitas koneksi TCP concurrent tinggi pada Nginx:
# Network tuning for high concurrency web servers
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 8192
fs.file-max = 2097152
Terapkan perubahan ini melalui Ansible task menggunakan modul sysctl agar konsisten di seluruh armada server.
10. Checklist Penerapan Produksi & Kesimpulan
Sebelum meluncurkan infrastruktur multi-cloud ini ke lingkungan live production, pastikan Anda telah melewati checklist validasi berikut:
- State Terraform disimpan di remote backend terenkripsi dengan locking mechanism aktif.
- Seluruh kredensial API, SSH Private Key, dan Database Password terenkripsi menggunakan Ansible Vault atau Secret Manager.
- Firewall (UFW / Security Groups) dikonfigurasi dengan prinsip Least Privilege (blokir semua port default kecuali port esensial).
- Layanan Fail2ban dan pembaruan keamanan otomatis (unattended-upgrades) aktif di semua OS node.
- Pengujian Disaster Recovery (uji matikan satu cloud provider dan pastikan failover berjalan mulus) telah berhasil disimulasikan.
Dengan mengawinkan kekuatan deklaratif Terraform dan fleksibilitas konfigurasi Ansible, organisasi Anda memiliki fondasi infrastruktur multi-cloud yang tangguh, dapat diulang, aman secara enterprise, dan siap menghadapi skala bisnis global masa depan.