Reference #
Mendeklarasikan data source adalah langkah pertama. Langkah berikutnya adalah menggunakan nilainya secara efektif — mereferensikan atribut yang tepat, memahami kapan nilai tersedia, dan menghindari jebakan yang muncul ketika data source bergantung pada resource yang belum tentu ada saat plan dijalankan.
flowchart TD
A["data source\ndideklarasikan"] --> B["Terraform\nRead API"]
B --> C["Attribute\ntersedia"]
C --> D["Referenced\ndengan data.X.Y.Z"]
style A fill:#3b82f6,stroke:#1e40af,color:#fff
style B fill:#f59e0b,stroke:#d97706,color:#fff
style C fill:#10b981,stroke:#059669,color:#fff
style D fill:#8b5cf6,stroke:#6d28d9,color:#fffCara Mereferensikan Atribut Data Source #
Referensi ke atribut data source menggunakan format data.<TYPE>.<NAME>.<ATTRIBUTE>.
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"]
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
}
}
# Referensi atribut data source:
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id # String — AMI ID
instance_type = "t3.micro"
}
resource "aws_launch_template" "web" {
image_id = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
# Referensi atribut lain dari data source yang sama
description = "Template menggunakan ${data.aws_ami.ubuntu.name} (${data.aws_ami.ubuntu.creation_date})"
}
Data Source untuk Membaca State Workspace Lain #
terraform_remote_state adalah data source khusus yang membaca output dari workspace Terraform lain. Ini memungkinkan arsitektur multi-workspace yang terpisah tapi terhubung.
# Workspace "networking" menyediakan VPC dan subnet
# Workspace "compute" membaca output dari workspace "networking"
data "terraform_remote_state" "networking" {
backend = "s3"
config = {
bucket = "my-terraform-state"
key = "production/networking/terraform.tfstate"
region = "ap-southeast-1"
}
}
# Gunakan output dari workspace networking
resource "aws_instance" "app" {
ami = data.aws_ami.ubuntu.id
subnet_id = data.terraform_remote_state.networking.outputs.private_subnet_ids[0]
vpc_security_group_ids = [
data.terraform_remote_state.networking.outputs.app_security_group_id
]
}
# Atau baca semua subnet sekaligus
resource "aws_autoscaling_group" "app" {
vpc_zone_identifier = data.terraform_remote_state.networking.outputs.private_subnet_ids
# ...
}
Data Source yang Bergantung pada Resource #
Ada kasus di mana data source perlu membaca resource yang baru saja dibuat dalam konfigurasi yang sama. Ini membutuhkan depends_on.
# SKENARIO: Membaca policy yang baru dibuat untuk menggabungkannya
resource "aws_iam_policy" "s3_read" {
name = "s3-read-policy"
policy = data.aws_iam_policy_document.s3_read.json
}
resource "aws_iam_policy" "cloudwatch_write" {
name = "cloudwatch-write-policy"
policy = data.aws_iam_policy_document.cloudwatch_write.json
}
# Data source ini membaca policy yang baru dibuat di atas
data "aws_iam_policy" "s3_read" {
name = "s3-read-policy"
# Tanpa depends_on, data source mungkin di-evaluate sebelum
# resource aws_iam_policy.s3_read selesai dibuat
depends_on = [aws_iam_policy.s3_read]
}
# Pola yang lebih umum: hindari situasi ini dengan referensi langsung
# Daripada baca via data source, referensikan resource langsung
resource "aws_iam_role_policy_attachment" "app_s3" {
role = aws_iam_role.app.name
policy_arn = aws_iam_policy.s3_read.arn # Referensi langsung — lebih bersih
# Bukan: data.aws_iam_policy.s3_read.arn
}
flowchart LR
subgraph DATASOURCE["data source"]
DS["data.aws_vpc.selected"]
end
subgraph RESOURCES["Resources"]
SG["aws_security_group"]
SUB["aws_subnet"]
end
DS -->|"vpc_id"| SG
DS -->|"cidr_block"| SUB
style DATASOURCE fill:#e3f2fd,stroke:#1565c0
style RESOURCES fill:#e8f5e9,stroke:#2e7d32Pola Data Source di Arsitektur Production #
# POLA 1: Dynamic AMI — selalu gunakan AMI terbaru yang sudah di-test
data "aws_ami" "app" {
most_recent = true
owners = ["self"] # AMI yang dibuat oleh akun ini sendiri (golden AMI)
filter {
name = "name"
values = ["app-server-*"]
}
filter {
name = "tag:Status"
values = ["tested"] # Hanya AMI yang sudah lulus testing
}
}
# POLA 2: Lookup resource yang dikelola tim lain
# Tim networking mengelola VPC dan menandainya dengan tag
data "aws_vpc" "main" {
tags = {
Name = "main-vpc"
Environment = var.environment
ManagedBy = "networking-team"
}
}
data "aws_subnets" "private" {
filter {
name = "vpc-id"
values = [data.aws_vpc.main.id]
}
tags = {
Tier = "private"
}
}
# POLA 3: Lookup berdasarkan naming convention yang konsisten
locals {
# Naming convention yang disepakati tim: <project>-<env>-<component>
vpc_name = "${var.project}-${var.environment}-vpc"
}
data "aws_vpc" "main" {
filter {
name = "tag:Name"
values = [local.vpc_name]
}
}
# POLA 4: Conditional data source — hanya query jika diperlukan
variable "use_existing_vpc" {
type = bool
default = false
}
data "aws_vpc" "existing" {
count = var.use_existing_vpc ? 1 : 0
tags = {
Name = "existing-vpc"
}
}
resource "aws_subnet" "app" {
vpc_id = var.use_existing_vpc ? data.aws_vpc.existing[0].id : aws_vpc.new.id
# ...
}
Membaca Atribut Akun dan Region #
Data source untuk informasi akun dan region sangat berguna untuk membuat konfigurasi yang portable — tidak perlu hardcode account ID atau region.
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
data "aws_partition" "current" {}
# Gunakan untuk ARN yang portable
resource "aws_iam_role_policy" "app" {
role = aws_iam_role.app.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = ["s3:GetObject"]
Resource = [
# Portable — tidak hardcode account ID atau region
"arn:${data.aws_partition.current.partition}:s3:::${var.bucket_name}/*"
]
}]
})
}
# Tag standar yang menyertakan informasi akun
locals {
standard_tags = {
AccountId = data.aws_caller_identity.current.account_id
Region = data.aws_region.current.name
ManagedBy = "terraform"
}
}
Data Source Lifecycle dan Refresh Behavior #
Data source di-refresh saat terraform plan dan terraform apply. Memahami kapan dan bagaimana data source di-refresh penting untuk konsistensi.
# Data source di-refresh SETIAP kali plan/apply dijalankan
# Ini berbeda dengan managed resource yang hanya di-refresh
# jika -refresh=true (default)
# Contoh: data.aws_ami.latest akan selalu mencari AMI terbaru
# Jika AMI baru dibuat antara plan dan apply, apply bisa menggunakan
# AMI yang berbeda dari yang direncanakan
# Untuk mem-pinning data source ke nilai tertentu:
# Gunakan filter yang spesifik atau simpan nilai di variable
flowchart TD
A["terraform plan"] --> B["Refresh data sources"]
B --> C["Read dari API
(ami-12345)"]
C --> D["Plan menggunakan
ami-12345"]
D --> E["Waktu berlalu...
AMI baru dibuat"]
E --> F["terraform apply"]
F --> G["Refresh data sources
lagi!"]
G --> H["Read dari API
(ami-67890) ⚠️"]
H --> I["Apply menggunakan
ami-67890 ≠ plan"]
style A fill:#e3f2fd,stroke:#1565c0
style H fill:#fff3e0,stroke:#e65100
style I fill:#ffebee,stroke:#c62828Performance Optimization untuk Data Source #
# Data source yang memanggil API bisa memperlambat plan
# jika ada banyak data source atau API lambat
# Tips: Gunakan filter yang spesifik untuk mengurangi API call
# BURUK: Mengambil semua AMI, lalu filter di Terraform
data "aws_ami" "all" {
most_recent = true
owners = ["self"]
# Mengembalikan SEMUA AMI milik kita → API response besar
}
# BAIK: Filter sedini mungkin di level API
data "aws_ami" "filtered" {
most_recent = true
owners = ["self"]
filter {
name = "name"
values = ["my-app-*"] # Filter di level API → response kecil
}
filter {
name = "state"
values = ["available"] # Hanya AMI yang available
}
}
Caching Data Source Results #
Data source dipanggil setiap kali terraform plan atau terraform apply. Untuk data yang jarang berubah, ini bisa memperlambat eksekusi.
# Solusi: Simpan hasil data source di local values
# Data source dipanggil sekali, tapi bisa dipakai berkali-kali
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}
locals {
# Simpan di locals untuk referensi mudah
region = data.aws_region.current.name
account_id = data.aws_caller_identity.current.account_id
# Build ARN pattern yang bisa dipakai di banyak tempat
arn_prefix = "arn:aws:${local.region}:${local.account_id}"
# Common tags yang include info dari data source
common_tags = {
Region = local.region
AccountId = local.account_id
ManagedBy = "terraform"
}
}
# Jika data source terlalu lambat karena API rate limit:
# 1. Kurangi jumlah data source (gabungkan filter)
# 2. Gunakan -refresh=false untuk skip refresh saat plan
terraform plan -refresh=false
# Hati-hati: state tidak di-refresh, bisa tidak akurat
# 3. Targeted refresh untuk resource tertentu
terraform plan -refresh-only -target=data.aws_ami.latest
---
## Data Source Authentication Context
Data source menggunakan credentials yang dikonfigurasi di provider block. Jika provider tidak terkonfigurasi, data source akan gagal.
```bash
# Data source menggunakan credentials dari:
# 1. Provider block (explicit configuration)
# 2. Environment variables (AWS_ACCESS_KEY_ID, etc.)
# 3. Shared credentials file (~/.aws/credentials)
# 4. IAM role (EC2 instance profile, ECS task role)
# 5. OIDC token (GitHub Actions, GitLab CI)
# Urutan prioritas:
# Explicit config > Env vars > Shared creds > IAM role > OIDC
# Data source dengan explicit provider
provider "aws" {
region = "ap-southeast-1"
profile = "production" # Menggunakan shared credentials
}
# Data source ini menggunakan provider di atas
data "aws_ami" "latest" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm-*"]
}
}
# Data source dengan different provider
provider "aws" {
alias = "us_east"
region = "us-east-1"
}
data "aws_ami" "latest_us" {
provider = aws.us_east
most_recent = true
owners = ["amazon"]
}
Ringkasan #
- Format referensi:
data.<TYPE>.<NAME>.<ATTRIBUTE>— konsisten dengan format referensi resource tapi dengan prefixdata..terraform_remote_stateuntuk membaca output workspace lain — berguna untuk arsitektur multi-workspace tapi menciptakan coupling yang perlu dipertimbangkan.depends_onuntuk data source yang membaca resource dalam konfigurasi yang sama — pastikan resource selesai dibuat sebelum data source di-evaluate.- Lebih baik referensi langsung ke resource daripada membaca via data source jika resource ada di konfigurasi yang sama.
- Pola golden AMI: gunakan filter
tag:Status = testeduntuk memastikan hanya AMI yang sudah divalidasi yang digunakan.aws_caller_identitydanaws_regionuntuk membuat konfigurasi yang portable — tidak perlu hardcode account ID atau region name di konfigurasi.
← Sebelumnya: Apa itu Datasource? Berikutnya: Anti-Pattern Datasource →