🛠️ Langkah Step-by-Step Setup Terraform
✅ Diagram Arstiketurnya
✅ Step 1: Persiapan Install Terraform di WSL
- sudo apt update && sudo apt install -y software-properties-common gnupg curl
- curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
- echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com
- $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
- sudo apt update && sudo apt install -y terraform
- terraform -v
✅ Step 2: Mengatur Kredensial AWS
Terraform menggunakan salah satu dari cara berikut untuk mengakses akun AWS kamu:
(a) File ~/.aws/credentials (paling umum)
Gunakan AWS CLI (kalau kamu install) atau buat file ini secara manual:
mkdir -p ~/.aws
vi ~/.aws/credentials
[default]
aws_access_key_id = YOUR_ACCESS_KEY
aws_secret_access_key = YOUR_SECRET_KEY
vi ~/.aws/config
[default]
region = ap-southeast-1
Kamu bisa dapatkan akses key dari: IAM > Users > Security credentials
✅ Step 3: Koneksi Internet
Karena Terraform akan:
-
Menghubungi AWS API
-
Mendownload provider plugin
Pastikan WSL kamu punya akses internet (cek ping google.com atau curl aws.amazon.com).
✅ Step 4: Struktur Terraform sederhana
Kita akan buat struktur Terraform sederhana untuk:
-
1 VPC
-
1 EC2 (Ubuntu t2.micro)
-
1 RDS (MySQL)
-
1 S3 Bucket
🔧variables.tf
variable "region" {
default = "ap-southeast-1"
}
variable "db_username" {
default = "tempAdmin"
}
variable "db_password" {
default = "tempAdmin954*"
}
🔧outputs.tf
output "ec2_public_ip" {
value = aws_instance.web.public_ip
}
output "rds_endpoint" {
value = aws_db_instance.mysql.endpoint
}
output "s3_bucket_name" {
value = aws_s3_bucket.app_bucket.bucket
}
🔧main.tf
provider "aws" {
region = var.region
}
# S3 Bucket
resource "aws_s3_bucket" "app_bucket" {
bucket = "my-webapp-bucket-${random_id.bucket_id.hex}"
force_destroy = true
}
resource "random_id" "bucket_id" {
byte_length = 4
}
# VPC dan Subnet default
data "aws_vpc" "default" {
default = true
}
# Perubahan di sini - menggunakan aws_subnets sebagai ganti aws_subnet_ids
data "aws_subnets" "default" {
filter {
name = "vpc-id"
values = [data.aws_vpc.default.id]
}
}
# Security Group
resource "aws_security_group" "web_sg" {
name = "web-sg"
description = "Allow HTTP, HTTPS, SSH, MySQL"
vpc_id = data.aws_vpc.default.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
self = true # Mengganti security_groups dengan self
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# EC2 Instance
resource "aws_instance" "web" {
ami = "ami-0c1907b6d738188e5" # Ubuntu 22.04 LTS - ap-southeast-1
instance_type = "t2.micro"
subnet_id = data.aws_subnets.default.ids[0] # Perubahan di sini
# Ganti ini:
#security_groups = [aws_security_group.web_sg.name]
# Menjadi ini:
vpc_security_group_ids = [aws_security_group.web_sg.id]
key_name = "wid" # ganti dengan nama key pair kamu
tags = {
Name = "WebAppInstance"
}
}
# RDS Instance
resource "aws_db_instance" "mysql" {
allocated_storage = 20
engine = "mysql"
engine_version = "8.0.35"
instance_class = "db.t3.micro"
db_name = "webappdb" # Ganti 'name' dengan 'db_name' untuk MySQL
username = var.db_username
password = var.db_password
db_subnet_group_name = aws_db_subnet_group.default.name
vpc_security_group_ids = [aws_security_group.web_sg.id]
skip_final_snapshot = true
backup_retention_period = 0
monitoring_interval = 0
publicly_accessible = false # Disarankan untuk keamanan
}
resource "aws_db_subnet_group" "default" {
name = "default-subnet-group"
subnet_ids = data.aws_subnets.default.ids # Perubahan di sini
}
Berikut penjelasan lengkap untuk konfigurasi main.tf Anda, bagian per bagian:
1. Provider AWS
provider "aws" {
region = var.region
}
-
Mendefinisikan provider AWS dan region yang akan digunakan
-
var.regionberarti nilai diambil dari variabel (biasa didefinisikan divariables.tf)
2. S3 Bucket
resource "aws_s3_bucket" "app_bucket" {
bucket = "my-webapp-bucket-${random_id.bucket_id.hex}"
force_destroy = true
}
resource "random_id" "bucket_id" {
byte_length = 4
}
-
Membuat bucket S3 dengan nama unik (mengandung random hex)
-
force_destroy = truememungkinkan bucket dihapus meski berisi data -
random_idmenghasilkan string random 4 byte (8 karakter hex) untuk keunikan nama bucket
3. Jaringan (VPC & Subnet)
data "aws_vpc" "default" {
default = true
}
data "aws_subnets" "default" {
filter {
name = "vpc-id"
values = [data.aws_vpc.default.id]
}
}
-
Menggunakan VPC default di akun AWS Anda
-
Mengambil semua subnet dalam VPC default tersebut
-
Data source (
data) digunakan untuk membaca infrastruktur yang sudah ada
4. Security Group
# Security Group
resource "aws_security_group" "web_sg" {
name = "web-sg"
description = "Allow HTTP, HTTPS, SSH, MySQL"
vpc_id = data.aws_vpc.default.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
self = true # Mengganti security_groups dengan self
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
Membuka akses untuk:
-
SSH (port 22) - dari mana saja (
0.0.0.0/0) -
HTTP (port 80) - dari mana saja
-
HTTPS (port 443) - dari mana saja
-
MySQL (port 3306) - hanya dari instance dalam SG yang sama (
self = true) -
Egress - mengizinkan semua traffic keluar
5. EC2 Instance
# EC2 Instance
resource "aws_instance" "web" {
ami = "ami-0c1907b6d738188e5" # Ubuntu 22.04 LTS - ap-southeast-1
instance_type = "t2.micro"
subnet_id = data.aws_subnets.default.ids[0] # Perubahan di sini
# Ganti ini:
#security_groups = [aws_security_group.web_sg.name]
# Menjadi ini:
vpc_security_group_ids = [aws_security_group.web_sg.id]
key_name = "wid" # ganti dengan nama key pair kamu
tags = {
Name = "WebAppInstance"
}
}
-
Membuat EC2 instance Ubuntu 22.04 tipe t2.micro
-
Ditempatkan di subnet pertama dari VPC default
-
Menggunakan security group yang sudah dibuat
-
key_nameharus diganti dengan key pair SSH yang sudah ada di AWS
6. RDS MySQL
resource "aws_db_instance" "mysql" {
allocated_storage = 20
engine = "mysql"
...
vpc_security_group_ids = [aws_security_group.web_sg.id]
publicly_accessible = false
}
-
Database MySQL 8.0 dengan storage 20GB
-
Menggunakan security group yang sama dengan EC2 (bisa akses MySQL)
-
publicly_accessible = falseberarti hanya bisa diakses dari dalam VPC -
skip_final_snapshot = true(hati-hati, ini menghilangkan backup saat RDS dihapus)
7. DB Subnet Group
resource "aws_db_subnet_group" "default" {
name = "default-subnet-group"
subnet_ids = data.aws_subnets.default.ids
}
-
Grup subnet untuk penempatan RDS
-
Menggunakan semua subnet default
Alur Kerja Infrastruktur:
-
Bucket S3 dibuat untuk menyimpan assets webapp
-
EC2 Instance akan:
-
Berjalan di subnet default
-
Bisa diakses via SSH/HTTP/HTTPS dari internet
-
Bisa akses database MySQL
-
-
RDS MySQL:
-
Hanya bisa diakses dari EC2 instance
-
Tidak terbuka ke internet
-
Berada di subnet private (asumsi subnet default termasuk private)
-
Yang Perlu Diperhatikan:
-
Security:
-
Port 22 terbuka untuk semua (sebaiknya dibatasi ke IP tertentu)
-
Database menggunakan SG yang sama dengan web server (idealnya dipisah)
-
-
Variabel:
-
var.region,var.db_username,var.db_passwordharus didefinisikan
-
-
Key Pair:
-
Ganti
your-key-namedengan nama key pair yang sudah ada di AWS
-
✅ Step 5: Perintah Terraform untuk membuat resources
Untuk uji coba:
# 0. Inisialisasi Terraform
terraform init
# 1. Buat dan simpan plan
terraform plan -out=tfplan
# 2. Review isi plan (opsional)
terraform show tfplan
# 3. Apply plan yang sudah disimpan
terraform apply tfplan
Arti pesan tersebut:
-
Tanpa opsi
-out: Ketika Anda hanya menjalankanterraform plan(tanpa menyimpan hasilnya), Terraform hanya menunjukkan preview perubahan yang akan dilakukan. -
Tidak ada jaminan: Jika Anda langsung menjalankan
terraform applysetelahnya, mungkin ada perbedaan antara:-
Apa yang ditampilkan di
plan -
Apa yang benar-benar di-apply
-
Mengapa ini penting?
-
Jika infrastruktur Anda berubah antara waktu
plandanapply(misalnya ada perubahan manual di AWS Console), hasil apply bisa berbeda dari yang di-plan. -
Terraform tidak bisa menjamin konsistensi karena tidak ada "snapshot" rencana yang disimpan
✅ Step 6: Persiapan Terraform untuk menghapus/destroy
Untuk menghapus/destroy semua resources AWS yang telah dibuat melalui Terraform, Anda bisa menggunakan perintah berikut:
Cara Destroy Resources Terraform:
-
Pertama, lihat dulu apa yang akan di-destroy (opsional tapi disarankan):
terraform plan -destroy -out=tfdestroyplan
Ini akan menunjukkan semua resources yang akan dihapus.
-
Eksekusi destroy:
terraform destroy
Terraform akan menampilkan daftar resources yang akan dihapus dan meminta konfirmasi.
-
Jika ingin langsung destroy tanpa konfirmasi:
terraform destroy -auto-approve
Beberapa catatan penting:
-
S3 Bucket:
-
Karena Anda mengatur
force_destroy = true, bucket akan dihapus meskipun berisi file -
Tanpa setting ini, destroy akan gagal jika bucket tidak kosong
-
-
RDS Instance:
-
Karena ada
skip_final_snapshot = true, database akan dihapus tanpa backup terakhir -
Jika ini di-production, sebaiknya buat snapshot manual dulu
-
-
Resources yang akan dihapus:
-
EC2 Instance
-
Security Group
-
RDS MySQL Instance
-
DB Subnet Group
-
S3 Bucket
-
Random ID resource
-
Jika mengalami error saat destroy:
-
Resources manual:
Pastikan tidak ada resources yang dibuat manual (di luar Terraform) yang bergantung pada resources yang dikelola Terraform -
Dependency error:
Terkadang perlu menjalankan destroy beberapa kali jika ada dependency issues -
Force destroy:
Untuk kasus tertentu bisa tambahkan flag-force, tapi hati-hati:terraform destroy -force
Best Practice Destroy:
-
Backup data penting dulu jika ada
-
Verifikasi environment yang akan di-destroy sudah benar
-
Gunakan workspace jika ingin memisahkan environment (dev/staging/prod)
-
Set timeout jika resources besar:
terraform destroy -timeout=30m
Setelah destroy selesai, Anda bisa verifikasi di AWS Console bahwa semua resources sudah terhapus. Terraform juga akan menghapus file status (terraform.tfstate) yang menyimpan informasi tentang infrastruktur yang dikelola.


No Comments