🛠️ 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.region
berarti 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 = true
memungkinkan bucket dihapus meski berisi data -
random_id
menghasilkan 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_name
harus 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 = false
berarti 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_password
harus didefinisikan
-
-
Key Pair:
-
Ganti
your-key-name
dengan 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 apply
setelahnya, mungkin ada perbedaan antara:-
Apa yang ditampilkan di
plan
-
Apa yang benar-benar di-apply
-
Mengapa ini penting?
-
Jika infrastruktur Anda berubah antara waktu
plan
danapply
(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