Praktik terbaik untuk gaya dan struktur umum

Dokumen ini memberikan rekomendasi gaya dan struktur dasar untuk konfigurasi Terraform Anda. Rekomendasi ini berlaku untuk modul Terraform yang dapat digunakan kembali dan konfigurasi root.

Panduan ini bukan merupakan pengantar untuk Terraform. Untuk pengantar penggunaan Terraform dengan Google Cloud, baca Mulai menggunakan Terraform.

Mengikuti struktur modul standar

  • Modul Terraform harus mengikuti struktur modul standar.
  • Mulai setiap modul dengan file main.tf, tempat resource berada secara default.
  • Dalam setiap modul, sertakan file README.md dalam format Markdown. Dalam file README.md, sertakan dokumentasi dasar tentang modul.
  • Tempatkan contoh dalam folder examples/, dengan subdirektori terpisah untuk setiap contoh. Untuk masing-masing contoh, sertakan file README.md mendetail.
  • Buat pengelompokan logis resource dengan file dan nama deskriptifnya sendiri, seperti network.tf, instances.tf, atau loadbalancer.tf.
    • Jangan memberikan file-nya sendiri kepada setiap resource. Kelompokkan resource berdasarkan tujuan bersama. Misalnya, gabungkan google_dns_managed_zone dan google_dns_record_set di dns.tf.
  • Dalam direktori root modul, hanya sertakan Terraform (*.tf) dan file metadata repositori (seperti README.md dan CHANGELOG.md).
  • Tempatkan dokumentasi tambahan dalam subdirektori docs/.

Menggunakan konvensi penamaan

  • Beri nama semua objek konfigurasi menggunakan garis bawah untuk membatasi beberapa kata. Praktik ini memastikan konsistensi dengan konvensi penamaan untuk jenis resource, jenis sumber data, dan nilai lainnya yang sudah ditetapkan. Konvensi ini tidak berlaku untuk argumen nama.

    Direkomendasikan:

    resource "google_compute_instance" "web_server" {
      name = "web-server"
    }
    

    Tidak direkomendasikan:

    resource "google_compute_instance" "web-server" {
      name = "web-server"
    }
    
  • Untuk menyederhanakan referensi ke resource yang merupakan satu-satunya dari jenisnya (misalnya, satu load balancer untuk seluruh modul), beri nama resource main.

    • Diperlukan upaya mental ekstra untuk mengingat some_google_resource.my_special_resource.id versus some_google_resource.main.id.
  • Untuk membedakan resource dari jenis yang sama satu sama lain (misalnya, primary dan secondary), berikan nama resource yang bermakna.

  • Buat nama resource dalam bentuk tunggal.

  • Dalam nama resource, jangan ulangi jenis resource. Contoh:

    Direkomendasikan:

    resource "google_compute_global_address" "main" { ... }
    

    Tidak direkomendasikan:

    resource "google_compute_global_address" "main_global_address" { … }
    

Menggunakan variabel dengan hati-hati

  • Deklarasikan semua variabel di variables.tf.
  • Berikan nama deskriptif untuk variabel yang relevan dengan penggunaan atau tujuannya:
    • Input, variabel lokal, dan output yang merepresentasikan nilai numerik—seperti ukuran disk atau ukuran RAM—harus diberi nama dengan unit (seperti ram_size_gb). Google Cloud API tidak memiliki unit standar, sehingga penamaan variabel dengan unit akan membuat unit input yang diharapkan jelas bagi pengelola konfigurasi.
    • Untuk unit penyimpanan, gunakan awalan satuan biner (pangkat 1024)—kibi, mebi, gibi. Untuk semua satuan pengukuran lainnya, gunakan awalan satuan desimal (pangkat 1000)—kilo, mega, giga. Penggunaan ini cocok dengan penggunaan dalam Google Cloud.
    • Untuk menyederhanakan logika bersyarat, berikan nama positif untuk variabel boolean—misalnya, enable_external_access.
  • Variabel harus memiliki deskripsi. Deskripsi otomatis disertakan dalam dokumentasi yang dibuat secara otomatis pada modul yang dipublikasikan. Deskripsi menambahkan konteks tambahan bagi developer baru yang tidak dapat diberikan oleh nama deskriptif.
  • Berikan jenis yang ditentukan untuk variabel.
  • Jika sesuai, berikan nilai default:
    • Untuk variabel dengan nilai yang tidak bergantung pada lingkungan (seperti ukuran disk), berikan nilai default.
    • Untuk variabel dengan nilai khusus lingkungan (seperti project_id), jangan berikan nilai default. Dengan cara ini, modul panggilan harus memberikan nilai yang bermakna.
  • Gunakan default kosong untuk variabel (seperti string atau daftar kosong) hanya jika membiarkan variabel tetap kosong adalah preferensi valid yang tidak ditolak API yang mendasarinya.
  • Gunakan variabel dengan bijak. Hanya buat parameter nilai yang harus bervariasi untuk setiap instance atau lingkungan. Saat memutuskan apakah akan mengekspos variabel, pastikan ada kasus penggunaan konkret untuk mengubah variabel tersebut. Jika hanya ada sedikit peluang bahwa variabel mungkin diperlukan, jangan mengekspos variabel tersebut.
    • Penambahan variabel dengan nilai default kompatibel dengan versi lama.
    • Penghapusan variabel tidak kompatibel dengan versi lama.
    • Jika literal digunakan kembali di beberapa tempat, Anda dapat menggunakan nilai lokal tanpa mengeksposnya sebagai variabel.

Mengekspos output

  • Atur semua output dalam satu file outputs.tf.
  • Berikan deskripsi yang bermakna untuk semua output.
  • Dokumentasikan deskripsi output di file README.md. Buat deskripsi secara otomatis di commit dengan alat seperti terraform-docs.
  • Tampilkan semua nilai berguna yang mungkin perlu dirujuk atau dibagikan oleh modul root. Terutama untuk modul open source atau modul yang sangat sering digunakan, ekspos semua output yang berpotensi untuk konsumsi.
  • Jangan meneruskan output secara langsung melalui variabel input, karena hal itu akan mencegahnya ditambahkan dengan benar ke grafik dependensi. Untuk memastikan bahwa dependensi implisit dibuat, pastikan referensi output diatribusikan dari resource. Dibandingkan mereferensikan variabel input untuk instance secara langsung, teruskan atribut seperti yang ditunjukkan di sini:

    Direkomendasikan:

    output "name" {
      description = "Name of instance"
      value       = google_compute_instance.main.name
    }
    

    Tidak direkomendasikan:

    output "name" {
      description = "Name of instance"
      value       = var.name
    }
    

Menggunakan sumber data

  • Tempatkan sumber data di samping resource yang mereferensikannya. Misalnya, jika Anda mengambil gambar yang akan digunakan dalam meluncurkan instance, tempatkan gambar tersebut di samping instance, bukan mengumpulkan resource data dalam filenya sendiri.
  • Jika jumlah sumber data menjadi besar, pertimbangkan untuk memindahkannya ke file data.tf khusus.
  • Untuk mengambil data yang relatif terhadap lingkungan saat ini, gunakan jenis interpolasi variabel atau resource.

Membatasi penggunaan skrip kustom

  • Gunakan skrip hanya jika diperlukan. Status resource yang dibuat melalui skrip tidak diperhitungkan atau dikelola oleh Terraform.
    • Hindari skrip kustom, jika memungkinkan. Hanya gunakan resource ini jika resource Terraform tidak mendukung perilaku yang diinginkan.
    • Setiap skrip kustom yang digunakan harus memiliki alasan yang terdokumentasi dengan jelas untuk rencana penghentian penggunaan yang ada dan ideal.
  • Terraform dapat memanggil skrip kustom melalui penyedia, termasuk penyedia lokal eksekutif.
  • Tempatkan skrip kustom yang dipanggil oleh Terraform di direktori scripts/.

Menyertakan skrip helper di direktori terpisah

  • Atur skrip helper yang tidak dipanggil oleh Terraform di direktori helpers/.
  • Dokumentasikan skrip helper di file README.md dengan penjelasan dan contoh pemanggilan.
  • Jika skrip helper menerima argumen, sediakan pemeriksaan argumen dan output --help.

Meletakkan file statis di direktori terpisah

  • File statis yang direferensikan Terraform tetapi tidak dijalankan (seperti skrip startup yang dimuat ke instance Compute Engine) harus diatur ke dalam direktori files/.
  • Letakkan HereDocs yang panjang dalam file eksternal, terpisah dari HCL-nya. Referensikan dengan fungsi file().
  • Untuk file yang dibaca menggunakan fungsi templatefile Terraform, gunakan ekstensi file .tftpl.
    • Template harus ditempatkan di direktori templates/.

Melindungi resource stateful

Untuk resource stateful, seperti database, pastikan perlindungan penghapusan diaktifkan. Contoh:

resource "google_sql_database_instance" "main" {
  name = "primary-instance"
  settings {
    tier = "D0"
  }

  lifecycle {
    prevent_destroy = true
  }
}

Menggunakan pemformatan bawaan

Semua file Terraform harus sesuai dengan standar terraform fmt.

Membatasi kompleksitas ekspresi

  • Batasi kompleksitas setiap ekspresi interpolasi individual. Jika banyak fungsi diperlukan dalam satu ekspresi, pertimbangkan untuk membaginya menjadi beberapa ekspresi menggunakan nilai lokal.
  • Jangan pernah ada lebih dari satu operasi ternary dalam satu baris. Sebagai gantinya, gunakan beberapa nilai lokal untuk membuat logika.

Menggunakan count untuk nilai bersyarat

Untuk membuat instance resource secara bersyarat, gunakan argumen meta count. Contoh:

variable "readers" {
  description = "..."
  type        = list
  default     = []
}

resource "resource_type" "reference_name" {
  // Do not create this resource if the list of readers is empty.
  count = length(var.readers) == 0 ? 0 : 1
  ...
}

Berhati-hatilah saat menggunakan variabel yang ditentukan pengguna ketika menetapkan variabel count untuk resource. Jika atribut resource disediakan untuk variabel tersebut (seperti project_id) dan resource tersebut belum ada, Terraform tidak dapat membuat rencana. Sebagai gantinya, Terraform melaporkan error value of count cannot be computed. Dalam kasus tersebut, gunakan variabel enable_x yang terpisah untuk melakukan komputasi logika bersyarat.

Menggunakan for_each untuk resource iterasi

Jika Anda ingin membuat beberapa salinan resource berdasarkan resource input, gunakan argumen meta for_each.

Memublikasikan modul ke registry

  • Modul yang dapat digunakan kembali: Publikasikan modul yang dapat digunakan kembali ke registry modul.

  • Modul open source: Publikasikan modul open source ke Terraform Registry.

  • Modul pribadi: Publikasikan modul pribadi ke registry pribadi.

Langkah selanjutnya