Bagaimana mengimpor infrastruktur yang sudah berjalan ke dalam OpenTofu memakai declarative import block maupun tofu import, lalu melakukan refactoring tanpa destroy dengan moved block serta tofu state mv, rm, list, dan show agar state selalu sinkron dengan realita.

Di episode 8 sebelumnya kita membahas advanced expressions, built-in functions, dan loops — bagaimana count, for_each, depends_on, lifecycle, serta for expressions dan ternary membuat HCL kalian dinamis dan ringkas. Tapi ada satu asumsi yang selama ini kita pegang diam-diam: semua infrastruktur dimulai dari nol oleh OpenTofu itu sendiri.
Realitas di lapangan hampir selalu berbeda. Ketika kalian bergabung dengan sebuah tim, sebagian besar infrastruktur sudah lebih dulu ada — dibangun lewat konsol AWS, dibuat oleh orang yang sudah pindah, atau bahkan hasil tooling lama. Mendeklarasikan ulang semua resource itu di HCL tidak cukup: OpenTofu akan melihat "dua versi" dan ingin menciptakan ulang semuanya. Mengerikan.
Di episode ini kita akan membahas state manipulation & import workflows — cara membawa infrastruktur eksisting masuk ke dalam state OpenTofu tanpa merusaknya, lalu melakukan refactoring kode tanpa destroy memakai moved block dan perintah tofu state. Dengan bekal ini, kalian bisa mengadopsi IaC untuk sistem yang sudah berjalan puluhan bulan.
Mengimpor artinya memberi tahu OpenTofu: "resource ini sudah ada di cloud dengan ID tertentu, jangan buat baru — catat saja ke state". Setelah itu, tofu plan memperlakukan resource sebagai bagian dari konfigurasi dan menghitung perbedaan menuju kondisi yang dideklarasikan.
Ada dua cara: CLI imperatif dan block deklaratif. Cara CLI langsung dan satu perintah:
tofu import aws_s3_bucket.data produksi-data-bucketCara deklaratif lebih disukai untuk produksi karena tercatat di kode dan bisa di-review di pull request:
import {
to = aws_s3_bucket.data
id = "produksi-data-bucket"
}Setelah block import ditulis, jalankan tofu plan untuk melihat perubahan yang akan terjadi, lalu tofu apply untuk merekam resource ke state. Idempoten dan dapat diulang — inilah keunggulan pendekatan deklaratif dibanding mengetik perintah CLI di terminal.
Tip
Tulis dulu definisi resource di main.tf (misalnya atribut bucket beserta tags), baru tambahkan block import. Saat apply, OpenTofu mengimpor lalu langsung merekonsiliasi perbedaan atribut. Lebih sedikit kejutan daripada mengimpor ke resource yang belum terdefinisi.
movedSetelah infrastruktur diadopsi, kebutuhan refactoring hampir pasti datang: mengganti nama resource, memindahkan resource ke dalam modul, atau menata ulang struktur. Jika kalian hanya mengubah nama di kode, OpenTofu akan menawarkan destroy lalu create — mematikan resource lama dan membuat yang baru. Untuk resource tanpa data, mungkin oke; untuk database dan instance produksi, itu bencana.
Block moved menyelesaikannya dengan memberi tahu OpenTofu bahwa alamat baru hanyalah hasil perubahan penamaan, bukan resource baru:
moved {
from = aws_instance.web
to = aws_instance.web_server
}
moved {
from = aws_instance.web_server
to = module.web.aws_instance.web
}Contoh pertama memindahkan alamat antar nama resource; contoh kedua menunjukkan pemindahan resource ke dalam modul. Setelah block moved ditambahkan, tofu plan tidak lagi menampilkan destroy — yang muncul hanyalah baris yang memberitahu bahwa state dipindahkan.
Warning
Jangan hapus block moved terlalu cepat. Simpan beberapa siklus apply agar semua anggota tim — termasuk yang jarang menjalankan OpenTofu — mendapat kesempatan menjalankan migrasi state-nya masing-masing. Menghapus block sebelum tim menyelaraskan state berpotensi memicu destroy yang tidak diinginkan.
tofu stateUntuk perubahan state yang bersifat satu kali atau diagnostik, OpenTofu menyediakan subcommand tofu state. Empat yang paling sering dipakai:
tofu state list
tofu state show aws_instance.web_server
tofu state mv aws_instance.web_server aws_instance.web
tofu state rm aws_instance.bekastofu state list menampilkan semua alamat resource yang tercatat.tofu state show memerinci atribut satu resource — berguna saat memverifikasi hasil import.tofu state mv memindahkan entri state — alternatif cepat untuk moved block saat perubahan bersifat ad-hoc.tofu state rm menghapus entri dari state.Perbedaan mendasar moved block vs tofu state mv: moved adalah bagian dari konfigurasi, terekam di Git, dan diproses otomatis setiap kali kalian menjalankan tofu plan atau tofu apply; tofu state mv adalah operasi sekali jalan di mesin yang menjalankannya — anggota tim lain harus melakukannya juga atau menerima moved di kemudian hari.
Warning
tofu state rm tidak menghapus resource di cloud — ia hanya melepaskannya dari state. Akibatnya, pada tofu plan berikutnya OpenTofu menganggap resource itu hilang dan menawarkan membuatnya lagi. Pastikan kalian benar-benar tahu apa yang dihapus, dan kombinasikan dengan state encryption dari episode 6 bila state kalian menyimpan data sensitif.
Berikut urutan yang aman untuk mengadopsi infrastruktur warisan:
main.tf dengan atribut yang sesuai kondisi nyata.import di import.tf untuk setiap resource.tofu init bila ada provider atau backend baru, lalu tofu plan.tofu apply untuk merekam state.moved dan biarkan beberapa siklus sebelum membersihkannya.tofu state list bahwa setiap resource berada di alamat yang diharapkan.Pada episode 9 ini kita menguasai pengelolaan state dan alur import:
import block (deklaratif) dan tofu import (CLI) membawa infrastruktur eksisting masuk ke state tanpa destroy.moved melakukan refactoring penamaan dan pemindahan ke modul tanpa recreate.tofu state list, show, mv, dan rm untuk diagnostik dan manipulasi state satu kali.Kemampuan ini membuat OpenTofu aman diterapkan pada sistem produksi yang sudah berjalan lama. Di episode 10 selanjutnya kita akan membahas Reusable Modules & OpenTofu Registry — membungkus infrastruktur menjadi modul yang bisa dipakai ulang dengan struktur main.tf, variables.tf, dan outputs.tf, lalu mengkonsumsinya dari registry, Git, atau local path. Sampai jumpa!