Variabel dan Output di OpenTofu
Pelajari cara membuat konfigurasi OpenTofu modular dan dinamis menggunakan variables.tf, outputs.tf, terraform.tfvars, validasi kustom, serta tipe data kompleks.
Daftar Isi
Pada bagian sebelumnya, kita menuliskan seluruh konfigurasi infrastruktur dalam satu file main.tf dengan nilai yang bersifat statis (hardcoded). Pendekatan tersebut memadai untuk latihan awal, namun di lingkungan nyata, konfigurasi harus fleksibel agar dapat digunakan ulang di berbagai environment (development, staging, hingga production).
OpenTofu secara otomatis membaca dan menggabungkan seluruh file berekstensi .tf yang berada di dalam direktori kerja yang sama. Dengan memecah konfigurasi menjadi beberapa file terpisah berdasarkan fungsinya, basis kode Anda menjadi jauh lebih rapi, terstruktur, dan mudah dirawat.
Struktur File Modular
Konvensi standar proyek OpenTofu memisahkan deklarasi input, logika resource, dan nilai kembalian ke dalam struktur berkas berikut:
infra/
├── main.tf # Logika resource dan provider
├── variables.tf # Deklarasi variabel input dan validasinya
├── outputs.tf # Deklarasi nilai output yang diekspos
└── terraform.tfvars # Nilai variabel konkret untuk environment tertentu (opsional)
1. Deklarasi Input (variables.tf)
File variables.tf berfungsi layaknya parameter fungsi dalam pemrograman. Di sini Anda mendefinisikan variabel apa saja yang dapat diterima oleh konfigurasi, tipe data yang diizinkan, nilai default, hingga aturan validasi kustom.
variable "container_name" {
description = "Nama container Docker di host"
type = string
default = "belajar-opentofu-nginx"
}
variable "nginx_image" {
description = "Docker image beserta tag versi"
type = string
default = "nginx:alpine"
}
variable "external_port" {
description = "Port host lokal yang di-forward ke port internal container"
type = number
default = 8080
# Validasi kustom untuk memastikan nomor port valid
validation {
condition = var.external_port > 0 && var.external_port <= 65535
error_message = "Nomor port harus berada di rentang 1 sampai 65535."
}
}
variable "enable_ssl" {
description = "Menentukan apakah konfigurasi HTTPS diaktifkan"
type = bool
default = false
}
Anatomi Blok variable
type: Menentukan tipe data variabel (misal:string,number,bool,list,map, atauobject). Jika diabaikan, tipenya otomatis dianggapany, tetapi sangat disarankan untuk selalu mendeklarasikan tipe secara eksplisit.default: Nilai acuan jika pengguna tidak menyediakan nilai lain. Variabel tanpa nilaidefaultberstatus required (wajib diisi oleh pengguna saat runtime).description: Dokumentasi singkat mengenai tujuan variabel tersebut.validation: Blok evaluasi aturan logika (condition) yang menghasilkan pesan error (error_message) jika input pengguna melanggar aturan.sensitive: Jika bernilaitrue, OpenTofu akan menyembunyikan nilai variabel ini dari log terminal pada saattofu plandantofu apply(sangat krusial untuk token API atau kata sandi).
2. Menggunakan Variabel di Kode Utama (main.tf)
Resource di dalam main.tf tidak lagi menggunakan nilai statis, melainkan merujuk ke variabel menggunakan sintaks var.<nama_variabel>:
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 4.6.0"
}
}
}
provider "docker" {
host = "unix:///var/run/docker.sock"
}
# Mengunduh image sesuai variabel var.nginx_image
resource "docker_image" "nginx" {
name = var.nginx_image
keep_locally = false
}
# Membuat container menggunakan variabel input
resource "docker_container" "web" {
image = docker_image.nginx.image_id
name = var.container_name
ports {
internal = 80
external = var.external_port
}
}
3. Mengekstrak Hasil Eksekusi (outputs.tf)
File outputs.tf mendefinisikan data penting yang ingin diekspos setelah proses tofu apply berhasil dieksekusi. Output ini berguna untuk menampilkan informasi ke terminal pengguna, diintegrasikan ke skrip CI/CD, atau dipanggil oleh modul OpenTofu lainnya.
output "container_id" {
description = "ID unik Docker container yang dibuat"
value = docker_container.web.id
}
output "web_url" {
description = "URL akses web service melalui peramban"
value = "http://localhost:${var.external_port}"
}
output "image_digest" {
description = "SHA digest dari Docker image yang digunakan"
value = docker_image.nginx.repo_digest
}
Setelah eksekusi selesai, Anda dapat melihat seluruh nilai output kapan saja tanpa perlu menjalankan apply ulang dengan perintah:
tofu output
Atau menampilkan nilai output tertentu secara spesifik:
tofu output web_url
# "http://localhost:8080"
4. Menyuplai Nilai Variabel (terraform.tfvars)
Jika Anda ingin mengubah nilai variabel tanpa menyentuh file .tf, Anda dapat membuat file bernama terraform.tfvars.
File terraform.tfvars otomatis dimuat oleh OpenTofu setiap kali perintah tofu plan atau tofu apply dijalankan:
container_name = "web-custom-staging"
external_port = 9090
nginx_image = "nginx:1.27-alpine"
Urutan Prioritas Variabel (Variable Precedence)
Bagaimana jika sebuah variabel didefinisikan di beberapa tempat sekaligus? OpenTofu mengevaluasi variabel berdasarkan hierarki urutan prioritas (dari prioritas tertinggi ke terendah):
- CLI Flag Langsung (
-varatau-var-file):tofu apply -var="external_port=8888" - File Otomatis
*.auto.tfvarsatau*.auto.tfvars.json(diurutkan berdasarkan nama file alfabetis). - File
terraform.tfvarsatauterraform.tfvars.json. - Environment Variables dengan prefiks
TF_VAR_:export TF_VAR_external_port=9000 - Nilai
defaultyang dideklarasikan di dalam blokvariablepada filevariables.tf.
Praktik Terbaik: Masukkan file
*.tfvarsyang memuat kredensial atau rahasia sensitif ke dalam berkas.gitignore. Buat fileterraform.tfvars.examplesebagai panduan konfigurasi bagi anggota tim lain.
5. Tipe Data Lanjutan di OpenTofu
Selain tipe data primitif (string, number, bool), OpenTofu mendukung tipe data koleksi (collection) dan struktural (structural) untuk skenario infrastruktur yang lebih kompleks.
A. List (Daftar Berurutan)
list menyimpan sekumpulan nilai dengan tipe data yang seragam dalam urutan indeks tertentu:
variable "allowed_ports" {
description = "Daftar port yang diizinkan untuk diakses"
type = list(number)
default = [80, 443, 8080]
}
# Contoh pengaksesan elemen list:
# var.allowed_ports[0] -> 80
# var.allowed_ports[1] -> 443
B. Map (Pasangan Kunci dan Nilai)
map menyimpan pasangan key-value di mana semua nilainya memiliki tipe data yang sama. Sangat ideal untuk pelabelan (tags) atau pemetaan konfigurasi berdasarkan nama environment:
variable "container_labels" {
description = "Label metadata untuk container"
type = map(string)
default = {
environment = "development"
owner = "devops-team"
project = "updeta-tutorial"
}
}
# Contoh pengaksesan nilai map:
# var.container_labels["environment"] -> "development"
C. Object (Struktur Data Kompleks)
object memungkinkan Anda membuat skema kustom dengan properti atribut yang memiliki tipe data berbeda-beda:
variable "server_config" {
description = "Spesifikasi lengkap server"
type = object({
hostname = string
memory_mb = number
restart_policy = string
is_production = bool
})
default = {
hostname = "nginx-server"
memory_mb = 512
restart_policy = "unless-stopped"
is_production = false
}
}
# Akses atribut:
# var.server_config.hostname -> "nginx-server"
# var.server_config.memory_mb -> 512
D. Kombinasi Koleksi: list(object)
Untuk mengelola sekumpulan resource berulang (seperti banyak port binding atau volume mount), gunakan list(object):
variable "port_mappings" {
description = "Daftar pemetaan port container ke host"
type = list(object({
internal = number
external = number
protocol = string
}))
default = [
{
internal = 80
external = 8080
protocol = "tcp"
},
{
internal = 443
external = 8443
protocol = "tcp"
}
]
}
# Mengakses elemen pertama:
# var.port_mappings[0].internal -> 80
# var.port_mappings[0].external -> 8080
6. Praktik Pengujian
Sekarang mari uji konfigurasi modular yang telah dibuat:
1. Uji Coba Override Nilai via terraform.tfvars
Pastikan file terraform.tfvars sudah dibuat dengan isi port 9090:
tofu plan
Perhatikan output rencana: OpenTofu akan mendeteksi bahwa port yang akan dipetakan adalah 9090 (menggantikan nilai default 8080).
2. Terapkan Konfigurasi
tofu apply -auto-approve
Setelah selesai, periksa output yang tercetak:
Outputs:
container_id = "5a2f8c4e..."
image_digest = "sha256:..."
web_url = "http://localhost:9090"
Uji web server Anda melalui terminal atau peramban:
curl http://localhost:9090
3. Menguji Validasi Kustom
Coba override variabel dengan nilai port yang tidak valid untuk melihat bagaimana blok validation bekerja:
tofu plan -var="external_port=70000"
OpenTofu akan langsung menolak eksekusi dan mencetak pesan kesalahan yang telah kita definisikan:
Error: Invalid value for variable
on variables.tf line 13:
13: variable "external_port" {
Nomor port harus berada di rentang 1 sampai 65535.
Fitur validasi ini sangat ampuh mencegah kesalahan konfigurasi sebelum perintah benar-benar menyentuh infrastruktur nyata.
Rangkuman & Langkah Berikutnya
Dalam artikel ini, Anda telah mempelajari:
- Cara memecah konfigurasi menjadi file terpisah:
variables.tf,main.tf,outputs.tf, danterraform.tfvars. - Cara mendeklarasikan variabel dengan tipe data, deskripsi, nilai default, dan blok
validation. - Hirarki urutan prioritas variabel OpenTofu (precedence).
- Penggunaan tipe data tingkat lanjut:
list,map,object, danlist(object). - Cara mengekstrak hasil eksekusi menggunakan
outputs.tfdan perintahtofu output.
Pada bagian selanjutnya, kita akan membahas State Management dan Remote Backend—mempelajari bagaimana tim berkolaborasi menggunakan OpenTofu secara aman tanpa benturan file state menggunakan S3 atau backend kompatibel lainnya.