Dokumen ini memberikan rekomendasi untuk mengekspresikan dependensi antara resource di konfigurasi Terraform Anda.
Lebih mendukung dependensi implisit daripada dependensi eksplisit
Ketergantungan sumber daya muncul ketika satu sumber daya bergantung pada keberadaan sumber lainnya Google Cloud Platform. Terraform harus bisa memahami dependensi ini untuk memastikan bahwa resource dibuat dalam urutan yang benar. Misalnya, jika resource A memiliki dependensi pada resource B, resource B dibuat sebelum resource A.
Dependensi konfigurasi Terraform dapat dibuat melalui
deklarasi dependensi implisit dan eksplisit.
Dependensi implisit dideklarasikan melalui
referensi ekspresi,
sedangkan dependensi eksplisit ditentukan dengan menggunakan
depends_on
argumen meta. Argumen depends_on
menentukan bahwa Terraform harus menyelesaikan
semua tindakan pada objek yang menjadi dependensi resource atau modul, sebelum
melanjutkan dengan objek dependen.
Sementara kedua pendekatan memastikan urutan operasi yang benar, dependensinya sering kali lebih efisien dalam merencanakan pembaruan dan penggantian resource. Hal ini karena Terraform dapat dengan cerdas melacak isian tertentu yang terlibat dalam dependensi implisit, untuk menghindari perubahan pada resource dependen jika kolom spesifik tersebut tetap tidak diubah dalam dependensi.
Dibandingkan dengan dependensi implisit, dependensi eksplisit menyampaikan informasi spesifik. Ini berarti bahwa Terraform hanya dapat merumuskan lebih banyak rencana konservatif untuk pembuatan, pembaruan, dan penggantian resource dalam tidak adanya pengetahuan tentang atribut tertentu yang membentuk ketergantungan. Dalam praktiknya, hal ini memengaruhi urutan pembuatan resource oleh Terraform dan cara Terraform menentukan apakah resource memerlukan update atau pengganti.
Kami merekomendasikan penggunaan dependensi eksplisit dengan argumen meta depends_on
hanya sebagai pilihan terakhir ketika ketergantungan antara dua sumber daya disembunyikan dan
tidak dapat dinyatakan melalui
dependensi implisit.
Dalam contoh berikut, layanan proyek yang diperlukan harus diaktifkan sebelum membuat set data BigQuery. Dependensi ini dideklarasikan secara eksplisit:
Tidak direkomendasikan:
module "project_services" {
source = "terraform-google-modules/project-factory/google//modules/project_services"
version = "~> 14.4"
project_id = var.project_id
activate_apis = [
"bigquery.googleapis.com",
"bigquerystorage.googleapis.com",
]
}
module "bigquery" {
source = "terraform-google-modules/bigquery/google"
version = "~> 5.4"
dataset_id = "demo_dataset"
dataset_name = "demo_dataset"
project_id = var.project_id
depends_on = [module.project_services] # <- explicit dependency
}
Contoh berikut menggantikan dependensi eksplisit dengan model
dependensi dengan mereferensikan argumen project_id
sebagai output project_id
dari resource project_services
:
Direkomendasikan:
module "bigquery" {
source = "terraform-google-modules/bigquery/google"
version = "~> 5.4"
dataset_id = "demo_dataset"
dataset_name = "demo_dataset"
project_id = module.project_services.project_id # <- implicit dependency
}
Penggunaan dependensi implisit memungkinkan deklarasi yang tepat atas dependensi, seperti menentukan informasi yang tepat yang perlu yang dikumpulkan dari objek upstream. Hal ini juga mengurangi kebutuhan untuk membuat perubahan di beberapa tempat, sehingga dapat mengurangi risiko kesalahan.
Mereferensikan atribut output dari resource dependen
Saat Anda membuat dependensi implisit dengan mereferensikan nilai dari upstream ke resource, pastikan untuk hanya mereferensikan atribut output, nilai yang belum diketahui. Tindakan ini akan memastikan bahwa Terraform menunggu resource upstream dibuat sebelum menyediakan resource saat ini.
Dalam contoh berikut, referensi resource google_storage_bucket_object
argumen nama resource google_storage_bucket
. Argumen telah diketahui
selama fase perencanaan Terraform. Artinya, saat Terraform membuat
resource google_storage_bucket_object
, kode ini tidak menunggu
Resource google_storage_bucket
dibuat karena mereferensikan resource
(nama bucket) tidak membuat dependensi implisit antara
google_storage_bucket_object
dan google_storage_bucket
. Hal ini mengalahkan
tujuan deklarasi dependensi implisit antara dua sumber daya.
Tidak direkomendasikan:
# Cloud Storage bucket
resource "google_storage_bucket" "bucket" {
name = "demo-bucket"
location = "US"
}
resource "google_storage_bucket_object" "bucket_object" {
name = "demo-object"
source = "./test.txt"
bucket = google_storage_bucket.bucket.name # name is an input argument
}
Sebagai gantinya, resource google_storage_bucket_object
harus mereferensikan id
atribut output dari resource google_storage_bucket_object
. Sejak id
adalah atribut output, nilainya hanya ditetapkan setelah pembuatan
resource telah dieksekusi. Oleh karena itu, Terraform akan menunggu pembuatan
resource google_storage_bucket_object
untuk diselesaikan sebelum memulai
pembuatan resource google_storage_bucket_object
.
Direkomendasikan:
resource "google_storage_bucket_object" "bucket_object" {
name = "demo-object"
source = "./test.txt"
bucket = google_storage_bucket.bucket.id # id is an output attribute
}
Terkadang tidak ada atribut output yang jelas untuk direferensikan. Misalnya,
pertimbangkan contoh berikut saat module_a
mengambil nama objek yang dihasilkan
sebagai input. Di dalam module_a
, nama file digunakan untuk membaca file. Jika
Anda menjalankan kode ini apa adanya, Anda akan mendapatkan pengecualian no such file or directory
,
yang disebabkan oleh Terraform yang mencoba
membaca file tersebut selama perencanaannya
, yaitu saat file belum dibuat. Dalam hal ini,
pemeriksaan atribut output dari resource local_file
mengungkapkan bahwa
tidak ada isian yang jelas yang dapat Anda gunakan sebagai pengganti input nama file
argumen.
Tidak direkomendasikan:
resource "local_file" "generated_file" {
filename = "./generated_file.text"
content = templatefile("./template.tftpl", {
project_id = var.project_id
})
}
module "module_a" {
source = "./modules/module-a"
root_config_file_path = local_file.generated_file.filename
}
Anda bisa mengatasi masalah ini dengan memasukkan dependensi eksplisit. Sebagai, pastikan menambahkan komentar tentang alasan diperlukannya dependensi eksplisit:
Direkomendasikan:
module "module_a" {
source = "./modules/module-a"
root_config_file_path = local_file.generated_file.filename
depends_on = [local_file.generated_file] # waiting for generated_file to be created
}
Langkah selanjutnya
- Pelajari praktik terbaik untuk komunikasi lintas konfigurasi.
- Pelajari praktik terbaik saat bekerja dengan resource Google Cloud.