Resource #

Resource adalah unit dasar dari konfigurasi Terraform. Setiap hal yang kamu ingin Terraform buat dan kelola — sebuah VM, sebuah database, sebuah DNS record, sebuah IAM role — dideklarasikan sebagai blok resource. Memahami cara resource bekerja, bagaimana ia berinteraksi satu sama lain, dan bagaimana Terraform mengelola lifecycle-nya adalah pondasi dari semua yang lebih kompleks di Terraform.

Anatomi Blok Resource #

Setiap blok resource memiliki struktur yang konsisten.

resource "<provider>_<type>" "<nama_lokal>" {
  # argumen = nilai
}

# Contoh nyata:
resource "aws_instance" "web_server" {
  #  │          │           │
  #  │          │           └── Nama lokal (hanya digunakan dalam konfigurasi ini)
  #  │          └────────────── Tipe resource (dari provider AWS)
  #  └───────────────────────── Provider prefix
  
  ami           = "ami-0abcdef1234567890"
  instance_type = "t3.micro"
  
  tags = {
    Name        = "web-server"
    Environment = "production"
  }
}

Nama lokal (web_server di atas) hanya bermakna di dalam konfigurasi Terraform — ia tidak muncul di AWS. Yang muncul di AWS adalah nilai dari argumen tags.Name. Nama lokal digunakan untuk mereferensikan resource ini dari tempat lain dalam konfigurasi.


Referensi Antar Resource #

Satu resource bisa mereferensikan atribut dari resource lain. Inilah yang membentuk dependency graph dan memungkinkan resource saling terhubung secara dinamis.

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "public" {
  # Referensi ke atribut resource lain: <type>.<nama_lokal>.<atribut>
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "ap-southeast-1a"
}

resource "aws_security_group" "web" {
  name   = "web-sg"
  vpc_id = aws_vpc.main.id  # Referensi ke VPC yang sama

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_instance" "web" {
  ami                    = "ami-0abcdef1234567890"
  instance_type          = "t3.micro"
  subnet_id              = aws_subnet.public.id       # dari subnet
  vpc_security_group_ids = [aws_security_group.web.id] # dari security group
}

Ketika kamu mereferensikan aws_vpc.main.id, Terraform tahu bahwa resource ini bergantung pada VPC — dan VPC harus dibuat lebih dulu.


Lifecycle Resource #

Setiap resource memiliki lifecycle: dibuat, mungkin diubah, dan akhirnya dihapus. Terraform mengelola ini secara otomatis, tapi kamu bisa mengkustomisasi perilakunya.

resource "aws_instance" "web" {
  ami           = "ami-0abcdef1234567890"
  instance_type = "t3.micro"

  lifecycle {
    # Buat resource baru sebelum menghapus yang lama
    # Berguna untuk resource yang tidak boleh down sedetikpun
    create_before_destroy = true

    # Tolak operasi destroy — Terraform akan error jika ada yang mencoba
    # menghapus resource ini (proteksi untuk resource kritis)
    prevent_destroy = true

    # Abaikan perubahan pada atribut tertentu
    # (berguna jika atribut dikelola di luar Terraform)
    ignore_changes = [
      tags["LastModified"],
      user_data,  # user_data sering diubah di luar Terraform
    ]
  }
}

Resource dengan Count dan For Each #

Terraform menyediakan cara untuk membuat beberapa instance resource sekaligus.

# Menggunakan count — untuk resource yang identik
resource "aws_subnet" "public" {
  count             = 3  # Buat 3 subnet
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.${count.index}.0/24"
  availability_zone = data.aws_availability_zones.available.names[count.index]

  tags = {
    Name = "public-subnet-${count.index + 1}"
  }
}

# Menggunakan for_each — untuk resource dengan konfigurasi berbeda-beda
resource "aws_iam_user" "team" {
  for_each = toset(["alice", "bob", "charlie"])
  
  name = each.key
  
  tags = {
    Name = each.key
  }
}

# Referensi ke resource yang dibuat dengan for_each
# aws_iam_user.team["alice"].arn
# aws_iam_user.team["bob"].arn
Prefer for_each daripada count jika resource-nya punya identitas yang berbeda-beda (nama, konfigurasi unik). count lebih cocok untuk resource yang benar-benar identik. Dengan count, menghapus elemen di tengah akan membuat Terraform menghapus dan membuat ulang semua resource setelahnya karena index bergeser.

Membaca Atribut Resource #

Setelah resource dibuat, Terraform menyimpan semua atributnya di state — termasuk atribut yang baru tersedia setelah resource dibuat (seperti IP address atau generated ID).

resource "aws_instance" "web" {
  ami           = "ami-0abcdef1234567890"
  instance_type = "t3.micro"
}

# Atribut yang baru tersedia setelah instance dibuat:
output "instance_public_ip" {
  value = aws_instance.web.public_ip  # Tersedia setelah apply
}

output "instance_id" {
  value = aws_instance.web.id  # ID yang digenerate AWS
}

Daftar lengkap atribut yang tersedia untuk setiap resource type bisa dilihat di dokumentasi provider masing-masing di registry.terraform.io.


Ringkasan #

  • Resource adalah unit dasar Terraform — setiap infrastruktur yang kamu kelola dideklarasikan sebagai blok resource "<type>" "<nama_lokal>".
  • Nama lokal hanya untuk referensi internal — ia tidak mempengaruhi nama resource di cloud, hanya digunakan untuk mereferensikan resource dalam konfigurasi.
  • Referensi antar resource (aws_vpc.main.id) membentuk dependency graph otomatis dan memungkinkan resource saling terhubung secara dinamis.
  • Lifecycle block mengizinkan kustomisasi perilaku: create_before_destroy, prevent_destroy, dan ignore_changes.
  • Gunakan for_each bukan count untuk resource dengan identitas berbeda — lebih aman saat ada perubahan di tengah daftar.
  • Atribut yang digenerate (IP, ID) tersimpan di state dan bisa direferensikan setelah terraform apply selesai.

← Sebelumnya: Provider   Berikutnya: State →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact