Apa itu Resource? #
Di section Concept, kamu sudah berkenalan dengan resource sebagai unit dasar konfigurasi Terraform. Di section ini, kita masuk lebih dalam — bagaimana resource berinteraksi satu sama lain, bagaimana Terraform mengelola lifecycle-nya, dan bagaimana menulis resource yang robust untuk infrastruktur production. Artikel ini membangun fondasi untuk topik-topik yang lebih dalam di section ini: lifecycle, dependency, dan operation.
Resource vs Data Source #
Salah satu kebingungan paling umum di Terraform adalah perbedaan antara resource dan data. Keduanya adalah blok konfigurasi, tapi perannya sangat berbeda.
# resource — Terraform MEMBUAT dan MENGELOLA ini
# Terraform bertanggung jawab atas lifecycle-nya: create, update, destroy
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "main-vpc"
}
}
# data — Terraform MEMBACA ini, tidak membuatnya
# Resource sudah ada di luar Terraform, kamu hanya ingin referensikan
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-*-22.04-amd64-server-*"]
}
}
# Menggunakan keduanya bersama
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id # AMI dari data source
instance_type = "t3.micro"
vpc_id = aws_vpc.main.id # VPC dari resource
}
Anatomi Lengkap Blok Resource #
# Struktur lengkap blok resource dengan semua bagiannya
resource "<PROVIDER>_<TYPE>" "<NAME>" {
# ─────────────────────────────────────────
# ARGUMEN — konfigurasi spesifik resource ini
# ─────────────────────────────────────────
ami = "ami-0abcdef1234567890"
instance_type = "t3.micro"
# Blok bersarang (nested block)
tags = {
Name = "web-server"
Environment = var.environment
}
# ─────────────────────────────────────────
# META-ARGUMENTS — berlaku untuk semua resource
# ─────────────────────────────────────────
# Dependency eksplisit
depends_on = [aws_iam_role_policy_attachment.node]
# Buat beberapa instance
count = 3
# atau: for_each = var.instance_map
# Gunakan provider non-default
provider = aws.us_east
# Kustomisasi lifecycle
lifecycle {
create_before_destroy = true
prevent_destroy = false
ignore_changes = [tags["LastModified"]]
}
}
Meta-arguments (depends_on, count, for_each, provider, lifecycle) adalah argumen khusus yang dikenali Terraform sendiri — bukan argumen dari provider. Mereka berlaku untuk semua resource, apapun tipe dan providernya.
Bagaimana Resource Direpresentasikan di State #
Setiap resource yang dibuat Terraform disimpan di state dengan identitas uniknya. Memahami struktur ini membantu saat kamu perlu berinteraksi dengan state secara langsung.
# Lihat semua resource di state
terraform state list
# Output:
# aws_instance.web
# aws_instance.workers[0]
# aws_instance.workers[1]
# aws_instance.workers[2]
# module.vpc.aws_vpc.main
# module.vpc.aws_subnet.public["ap-southeast-1a"]
# Lihat detail satu resource di state
terraform state show aws_instance.web
# Output:
# # aws_instance.web:
# resource "aws_instance" "web" {
# ami = "ami-0abcdef1234567890"
# id = "i-0abcdef1234567890"
# instance_type = "t3.micro"
# private_ip = "10.0.1.42"
# public_ip = "54.123.45.67"
# ... (semua atribut, termasuk yang digenerate AWS)
# }
Address resource di state mengikuti format: <type>.<name> untuk resource biasa, <type>.<name>[index] untuk resource dengan count, dan <type>.<name>["key"] untuk resource dengan for_each.
Resource Address dan Cara Mereferensikannya #
Setiap resource memiliki address yang bisa direferensikan dari tempat lain dalam konfigurasi.
# Format referensi: <TYPE>.<NAME>.<ATTRIBUTE>
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id # Referensi ke atribut "id" dari aws_vpc.main
}
# Untuk resource dengan count:
resource "aws_subnet" "private" {
count = 3
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index + 10}.0/24"
}
resource "aws_route_table_association" "private" {
count = 3
subnet_id = aws_subnet.private[count.index].id # Akses per index
route_table_id = aws_route_table.private.id
}
# Semua subnet sekaligus menggunakan splat expression:
output "private_subnet_ids" {
value = aws_subnet.private[*].id # ["subnet-001", "subnet-002", "subnet-003"]
}
Pola Penulisan yang Konsisten #
Konsistensi dalam cara menulis resource membuat konfigurasi lebih mudah dibaca dan di-review.
# POLA YANG DIREKOMENDASIKAN:
resource "aws_instance" "web" {
# 1. Argumen required (wajib) di atas
ami = var.ami_id
instance_type = var.instance_type
# 2. Argumen optional yang penting
subnet_id = aws_subnet.public.id
vpc_security_group_ids = [aws_security_group.web.id]
iam_instance_profile = aws_iam_instance_profile.web.name
# 3. Blok bersarang
root_block_device {
volume_size = 20
volume_type = "gp3"
encrypted = true
}
# 4. Tags selalu di akhir
tags = merge(
var.common_tags,
{
Name = "web-server"
Role = "web"
}
)
# 5. Lifecycle di paling akhir (jika ada)
lifecycle {
create_before_destroy = true
}
}
Ringkasan #
resourceuntuk membuat,datauntuk membaca — resource dikelola Terraform, data source hanya dibaca dari yang sudah ada.- Meta-arguments (
depends_on,count,for_each,provider,lifecycle) berlaku untuk semua resource, bukan argumen dari provider.- Address resource di state mengikuti format
<type>.<name>— penting diketahui untuk operasiterraform statedan referensi antar resource.- Referensi menggunakan format
<type>.<name>.<attribute>— ini yang membentuk dependency graph otomatis Terraform.- Splat expression (
[*]) untuk mengakses semua instance sekaligus dari resource dengancount.- Konsistensi penulisan — required args dulu, optional, nested blocks, tags, lifecycle — membuat review lebih mudah.