Kuasai infrastructure-as-code dengan membangun deployment kontainer yang dapat direproduksi menggunakan Terraform di atas Docker. Pelajari pipeline dari penyiapan provider hingga CI/CD otomatis.
Saya telah menghabiskan banyak waktu mengelola kontainer Docker secara manual di lingkungan pengembangan dan produksi. Konfigurasi yang tidak selaras, state yang melenceng, dan ketidakpastian apakah setelan lokal saya cocok dengan produksi selalu menghantui tiap deployment. Saat saya menemukan Docker provider milik Terraform, semuanya berubah.
Dalam tutorial ini, saya akan memandu Anda mengintegrasikan Terraform dengan Docker untuk membuat infrastruktur yang dapat direproduksi dan dikendalikan versinya. Anda akan belajar cara mem-provision kontainer, mengelola jaringan dan volume, menerapkan batas sumber daya, serta menjaga state di seluruh tim Anda.
Baik Anda mengelola build server maupun mengorkestrasi microservices, buka terminal Anda dan mari ubah cara Anda menangani infrastruktur Docker.
Jika Anda baru di Docker, saya menyarankan memulai dengan kursus Introduction to Docker kami.
Apa Itu Integrasi Terraform Docker?
Terraform adalah alat infrastructure-as-code yang mengelola siklus hidup sumber daya melalui alur kerja deklaratif. Alih-alih menjalankan perintah Docker satu per satu, Anda mendefinisikan state infrastruktur yang diinginkan di berkas konfigurasi. Terraform kemudian mengeksekusi siklus hidup plan-apply-destroy: menghitung perubahan yang diperlukan, menampilkan pratinjau, dan menerapkannya hanya setelah disetujui.
Provider Terraform Docker berfungsi sebagai lapisan translasi antara kode HashiCorp Configuration Language (HCL) dan Docker API. Saat menulis resource “docker_container" dalam konfigurasi, provider mengonversi deklarasi tersebut menjadi panggilan Docker API yang sesuai. Abstraksi ini berarti sumber daya Docker dapat dikelola menggunakan alur kerja yang sama seperti untuk infrastruktur cloud.
Compose mengelola kontainer melalui pendekatan berbasis proyek menggunakan berkas YAML, namun tidak memelihara state file yang melacak apa yang benar-benar ada.
Sebaliknya, Terraform mencatat setiap sumber daya yang dibuatnya di terraform.tfstate, memungkinkannya mendeteksi drift antara konfigurasi saya dan realitas. Jika seseorang memodifikasi kontainer secara manual, Terraform akan menyadarinya dan dapat mengembalikannya ke state yang didefinisikan.
Pendekatan ini unggul dalam beberapa skenario:
Untuk build server yang dapat direproduksi, Anda dapat menghancurkan dan membuat ulang seluruh lingkungan dengan satu perintah, menjamin konsistensi.
Di lingkungan pengujian, Anda dapat menyalakan infrastruktur terisolasi untuk setiap run pengujian.
Untuk deployment yang immutable, Anda mengganti kontainer sepenuhnya alih-alih memodifikasinya di tempat, sehingga mengurangi risiko deployment.
Prasyarat dan Instalasi
Sebelum menyelami konfigurasi Terraform, mari verifikasi bahwa alat yang diperlukan telah terpasang dan dikonfigurasi dengan benar.
Memenuhi persyaratan sistem
Pertama, pastikan Docker Engine berjalan di mesin Anda.
Linux: Periksa dengan docker ps
macOS atau Windows: Pastikan Docker Desktop terpasang dan berjalan
Terraform provider membutuhkan akses ke Docker daemon, jadi Anda perlu memastikan pengguna Anda memiliki izin untuk mengakses Unix socket di /var/run/docker.sock pada Linux atau named pipe di Windows.
Selanjutnya, pasang Terraform CLI dari situs resmi HashiCorp. Menginstal Terraform bervariasi menurut sistem operasi:
Linux: Unduh paket yang sesuai atau gunakan manajer paket distribusi Anda.
macOS: Gunakan Homebrew. Pertama, pasang HashiCorp tap dengan brew tap hashicorp/tap, lalu pasang Terraform dengan perintah brew install hashicorp/tap/terraform.
Windows: Unduh biner dari hashicorp.com dan tambahkan ke PATH Anda, atau gunakan Chocolatey: choco install terraform.
Setelah terpasang, verifikasi instalasi dengan menjalankan terraform version.
Dengan Docker dan Terraform terverifikasi, langkah berikutnya adalah menata berkas proyek agar mudah dipelihara.
Mengonfigurasi struktur proyek
Proyek Terraform diuntungkan dari pendekatan yang jelas dan terstruktur. Biasanya, saya membuat direktori khusus untuk proyek Terraform saya dan menginisialisasi version control:
mkdir terraform-docker-project
cd terraform-docker-project
git initDidukung oleh
Version control sangat penting untuk infrastructure-as-code. Setiap perubahan pada infrastruktur Docker harus dilacak, ditinjau, dan dapat dibalik. Biasanya saya menambahkan directory kerja Terraform dan berkas state ke.gitignore untuk mengecualikannya dari version control:
.terraform/
*.tfstate
*.tfstate.backup
.terraform.lock.hclDidukung oleh
Terakhir, saya membuat berkas kosong main.tf tempat saya akan mendefinisikan infrastruktur. Berkas ini akan menampung konfigurasi provider dan definisi resource.
Terraform Docker Provider dan Resource Inti
Dengan struktur proyek siap, saatnya mengonfigurasi Docker provider dan mulai mendefinisikan resource.
Menginisialisasi Docker provider
Pertama, dengan menambahkan konfigurasi provider ke main.tf:
Blok required_providers menentukan dari mana Terraform harus mengunduh plugin provider. Menggunakan batasan versi (~> 3.0) memungkinkan pembaruan versi minor sekaligus mencegah perubahan yang berpotensi merusak. Untuk host Docker jarak jauh, Anda dapat mengubah parameter host menjadi semacam tcp://192.168.1.100:2376.
Sekarang jalankan terraform init di direktori root proyek. Ini mengunduh plugin Docker provider dan menyimpannya di .terraform/providers/. Perintah ini menampilkan versi tepat yang diinstal, dan Terraform membuat berkas kunci untuk memastikan versi provider konsisten di seluruh tim saya.
Mengelola image kontainer
Setelah provider diinisialisasi, langkah berikutnya adalah mendefinisikan image kontainer. Sebelum membuat kontainer, Anda perlu mengelola image yang akan digunakan, jadi Anda perlu mendefinisikan resource image:
resource "docker_image" "nginx" {
name = "nginx:1.29"
keep_locally = true
}Didukung oleh
Tambahkan resource ini tepat setelah blok provider. Parameter keep_locally penting karena mencegah Terraform menghapus image saat saya menjalankan terraform destroy. Ini berguna ketika beberapa kontainer berbagi image yang sama atau saat saya ingin mempertahankan image yang di-cache antar deployment.
Untuk deployment produksi, kunci image berdasarkan digest SHA256 untuk memastikan immutability:
resource "docker_image" "nginx" {
name = "nginx@sha256:b60f25eb5acdd79172de1a289891d9cfe4fc3669daddeeb68619240cbe839d9f"
}Didukung oleh
Digest dapat diperoleh dari container registry. Untuk image Docker Hub seperti nginx, Anda dapat menemukannya di situs resmi Docker pada bagian Tags. Menggunakan digest menjamin bahwa binary image yang persis sama dideploy setiap saat, bahkan jika seseorang mendorong image baru dengan tag yang sama.
Menyediakan kontainer Docker
Setelah image didefinisikan, langkah berikutnya adalah membuat kontainer yang mereferensikannya:
Image direferensikan menggunakan docker_image.nginx.image_id. Ini membuat dependensi implisit karena Terraform tidak akan mencoba membuat kontainer sampai image ada. Blok ports memetakan port internal kontainer 80 ke port 8080 host saya, setara dengan docker run -p 8080:80.
Variabel lingkungan diletakkan dalam daftar env sebagai string. Terraform akan membuat ulang kontainer jika ada parameter yang berubah, memastikan infrastruktur yang berjalan selalu cocok dengan konfigurasi.
Pada tahap ini, jalankan terraform plan untuk melihat apa yang akan dibuat Terraform, lalu terraform apply untuk mem-provision infrastruktur. Terraform akan membuat image dan kontainer. Anda dapat memverifikasinya dengan memeriksa resource di Docker Desktop atau menjalankan docker ps di terminal.
Jaringan, Penyimpanan, dan Batas Sumber Daya di Terraform
Sekarang Anda telah menjalankan kontainer dasar dan memahami alur kerja inti, mari perluas infrastruktur dengan fitur siap produksi. Bagian berikut membangun fondasi ini dengan menambahkan jaringan, penyimpanan persisten, dan batasan sumber daya, yang semuanya penting untuk deployment di dunia nyata
Mengelola jaringan
Untuk mengaktifkan komunikasi antar kontainer sambil menjaga isolasi, membuat jaringan khusus sangat penting. Berikut cara membuat jaringan terisolasi untuk mengontrol konektivitas kontainer. Tambahkan resource berikut ke berkas main.tf:
resource "docker_network" "app_network" {
name = "application_net"
driver = "bridge"
}Didukung oleh
Sekarang tambahkan kontainer kedua yang menggunakan jaringan ini. Tambahkan ini setelah kontainer web:
resource "docker_container" "api" {
name = "api-server"
image = docker_image.nginx.image_id
networks_advanced {
name = docker_network.app_network.name
}
}Didukung oleh
Ini membuat jaringan bridge khusus dan menautkan kontainer api ke sana. Kontainer pada jaringan yang sama dapat berkomunikasi menggunakan nama kontainer sebagai hostname, yang sangat cocok untuk arsitektur microservices.
Verifikasi isolasi jaringan dengan menjalankan docker network inspect application_net dan memastikan hanya kontainer yang dimaksud yang terhubung. Pastikan Anda menjalankan perintah ini setelah membuat resource menggunakan terraform plan dan terraform apply.
Dengan jaringan dikonfigurasi untuk komunikasi antar kontainer, aspek penting berikutnya adalah persistensi data.
Mengonfigurasi volume persisten
Untuk data yang harus tetap ada setelah kontainer di-restart, tambahkan resource volume. Sisipkan ini sebelum definisi kontainer:
resource "docker_volume" "db_data" {
name = "postgres_data"
}Didukung oleh
Sekarang tambahkan kontainer basis data yang menggunakan volume ini:
Volume terkelola seperti ini dibuat dan dikendalikan oleh Docker, disimpan di direktori data Docker. Untuk berbagi berkas konfigurasi dari host, gunakan bind mount dengan menentukan host_path alih-alih volume_name.
Setelah memastikan data tetap ada saat kontainer di-restart, sama pentingnya untuk mencegah satu kontainer memonopoli sumber daya sistem.
Menetapkan batas sumber daya
Di luar penyimpanan, mengendalikan seberapa banyak CPU dan memori yang dapat dikonsumsi setiap kontainer sangat penting untuk stabilitas sistem. Untuk mencegah kontainer menggunakan sumber daya berlebihan, terapkan batas sumber daya.
Walaupun Docker memungkinkan pembaruan beberapa batas sumber daya di tempat, model deklaratif Terraform sering kali memerlukan penggantian kontainer untuk memastikan state cocok dengan konfigurasi Anda. Untuk mencegah downtime selama penggantian ini, kita gunakan aturan lifecycle create_before_destroy.
Penting: Kita harus menghapus argumen name yang tetap untuk mencegah konflik penamaan selama proses penggantian. Salah satu opsi adalah menggunakan argumen name_prefix sebagai gantinya.
Parameter memory membatasi RAM dalam megabita. Parameter cpu_shares bekerja berbeda. Ini adalah bobot relatif yang dipakai saat terjadi kontensi CPU. Kontainer dengan 1024 shares akan memperoleh dua kali waktu CPU dibandingkan yang 512 shares, tetapi hanya ketika host berada di bawah beban.
Untuk batas CPU yang ketat, Anda juga dapat menggunakan cpu_set untuk mem-pin kontainer ke core CPU tertentu:
Validasi batas ini dengan menjalankan docker inspect background-worker --format='{{.HostConfig.Memory}} {{.HostConfig.CpuShares}} dan memeriksa nilai Memory dan NanoCpus sesuai dengan konfigurasi.
Sekali lagi, seperti diuraikan di atas, Anda perlu menjalankan terraform plan dan terraform apply terlebih dahulu untuk membuat resource.
Pada titik ini, berkas main.tf berisi konfigurasi provider, satu image, satu jaringan, satu volume, dan tiga kontainer dengan berbagai konfigurasi.
Variabel, Modul, dan Rahasia di Terraform
Seiring pertumbuhan infrastruktur, nilai yang di-hardcode menjadi tidak fleksibel. Bagian ini menunjukkan cara membuat konfigurasi dapat digunakan kembali menggunakan variabel, modul, dan penanganan rahasia yang tepat.
Menggunakan variabel input
Langkah pertama untuk membuat konfigurasi fleksibel adalah mengekstrak nilai yang di-hardcode menjadi variabel yang dapat dengan mudah diubah tanpa memodifikasi kode utama. Ini dapat dilakukan dengan membuat berkas baru bernama variables.tf di direktori yang sama:
variable "web_port" {
description = "External port for web container"
type = number
default = 8080
validation {
condition = var.web_port > 1024 && var.web_port < 65535
error_message = "Port must be between 1024 and 65535."
}
}Didukung oleh
Sekarang perbarui kontainer web di main.tf untuk menggunakan variabel ini:
Saat menjalankan terraform apply, Terraform akan membaca nilai dari berkas ini secara otomatis. Alternatifnya, teruskan nilai melalui baris perintah: terraform apply -var="web_port=9000".
Membuat modul yang dapat digunakan kembali
Variabel menyelesaikan masalah nilai yang di-hardcode, tetapi bagaimana jika Anda perlu menerapkan pola lengkap yang sama beberapa kali, lengkap dengan semua resource-nya?
Di sinilah modul unggul. Anggap modul sebagai cetak biru yang menggabungkan semua bagian terpisah itu menjadi satu paket, memungkinkan Anda ‘mencetak’ seluruh setup kompleks tersebut sebagai satu kesatuan.
Terakhir, buat berkas output modules/web-app/outputs.tf, yang terutama digunakan untuk menampilkan di terminal nilai yang diinginkan setelah menjalankan terraform apply:
output "container_ip" {
value = docker_container.app.network_data[0].ip_address
description = "IP address of the application container"
}Didukung oleh
Setelah menambahkan definisi modul, jalankan terraform init untuk memasang modul, lalu terraform apply untuk membuat kedua kontainer dari templat yang sama. Anda seharusnya dapat melihat semua resource di Docker Desktop.
Dengan pola infrastruktur yang dapat digunakan kembali melalui modul, masih ada satu aspek penting dalam manajemen konfigurasi: menangani informasi sensitif seperti kata sandi dan kunci API secara aman.
Menangani data sensitif
Nilai sensitif, seperti kata sandi basis data, tidak boleh di-hardcode. Sebagai gantinya, Anda dapat menggunakan berkas variables.tf dan menetapkan sensitive = true:
variable "db_password" {
description = "Database root password"
type = string
sensitive = true
}Didukung oleh
Sekarang perbarui kontainer basis data di main.tf untuk mereferensikan kata sandi basis data:
Alih-alih menaruh kata sandi di terraform.tfvars dan meng-hardcode-nya, tetapkan sebagai variabel lingkungan:
exportTF_VAR_db_password="your-secure-password"
terraform applyDidukung oleh
Flag sensitive = true mencegah Terraform menampilkan nilai di output konsol.
Namun, nilai-nilai ini disimpan sebagai teks biasa di terraform.tfstate, jadi untuk memastikan berkas ini aman, kita dapat mengamankannya menggunakan backend jarak jauh dengan enkripsi. Mari jelajahi cara melakukannya.
Manajemen State Terraform dan Integrasi CI/CD
Bagian ini membahas mekanisme state dan alur kerja otomatisasi yang penting untuk deployment produksi. Namun sebelum menerapkan otomatisasi, penting untuk memahami bagaimana Terraform melacak infrastruktur Anda melalui berkas state-nya.
Memahami mekanisme state
State adalah fondasi kemampuan Terraform untuk mengelola infrastruktur. Berkas terraform.tfstate memetakan konfigurasi ke ID kontainer Docker nyata dan atribut resource. Saat menjalankan terraform apply, Terraform membandingkan state ini dengan konfigurasi dan menghitung perubahan minimal yang diperlukan.
Periksa state saat ini dengan terraform show, yang menampilkan setiap resource yang dikelola. Untuk tim, berkas state lokal menimbulkan masalah, konflik, dan potensi kehilangan data. Solusinya adalah backend jarak jauh.
Untuk alur kerja berfokus Docker tanpa infra cloudstructure, Terraform Cloud tingkat gratis sangat ideal. Tambahkan blok backend ke bagian terraform di main.tf:
Buat akun gratis di situs Terraform. Kemudian, jalankan terraform login untuk melakukan autentikasi dengan token yang disediakan, dan lalu terraform init untuk memigrasikan state. Ini menyediakan penguncian state di workspace jarak jauh dan kolaborasi tim tanpa infrastruktur cloud.
Namun, Anda juga dapat membuat backend jarak jauh di penyedia Cloud seperti AWS atau GCP.
Mengotomatisasi alur kerja
Dengan manajemen state yang dikonfigurasikan dan disimpan secara jarak jauh, infrastruktur siap untuk kolaborasi tim. Bagian terakhir adalah mengotomatisasi proses deployment melalui pipeline CI/CD, memastikan perubahan yang konsisten dan dapat ditinjau.
Workflow ini menjalankan terraform plan pada setiap pull request, menampilkan kepada reviewer perubahan infrastruktur apa yang akan terjadi. Saat perubahan digabungkan ke main, terraform apply dieksekusi secara otomatis, memastikan setiap perubahan infrastruktur melalui proses tinjauan yang sama seperti perubahan kode.
Pemecahan Masalah Terraform Docker
Bahkan dengan konfigurasi yang cermat, masalah bisa muncul. Memahami masalah umum dan kapan mempertimbangkan alternatif membantu membuat keputusan arsitektural yang lebih baik.
“Permission denied”
Kesalahan paling umum di Linux adalah "permission denied" saat menghubungkan ke socket Docker. Ini terjadi ketika pengguna tidak memiliki izin untuk mengakses /var/run/docker.sock. Perbaiki dengan menambahkan pengguna ke grup docker:
Di Windows dengan WSL2, masalah konektivitas muncul karena path socket berbeda. Pastikan setelan Docker Desktop "Expose daemon on tcp://localhost:2375 without TLS" diaktifkan, lalu perbarui provider di main.tf:
provider "docker" {
host = "tcp://localhost:2375"
}Didukung oleh
Kegagalan autentikasi registry privat
Untuk registry Docker privat, tambahkan autentikasi ke blok provider, definisikan kredensial sebagai variabel, dan tetapkan melalui variabel lingkungan untuk menghindari masalah akibat hardcode.
Di luar pemecahan masalah, sama berharganya untuk memahami kapan alat lain mungkin lebih tepat daripada Terraform untuk kasus penggunaan spesifik Anda.
Terraform vs Kubernetes
Kubernetes menawarkan fitur orkestrasi yang jauh lebih canggih :
Self-healing
Penjadwalan lanjutan
Penemuan layanan
Load balancing bawaan
Untuk deployment multi-node yang kompleks dengan persyaratan high availability, Kubernetes adalah pilihan yang lebih baik. Terraform dapat mem-provision infrastruktur Kubernetes, sementara Helm atau manifest Kubernetes menangani deployment aplikasi.
Terraform vs Ansible
Ansible unggul dalam manajemen konfigurasi di dalam kontainer. Sementara Terraform mem-provision infrastruktur, Ansible mengelola konfigurasi perangkat lunak dan pemasangan paket. Keduanya sering bekerja bersama: Terraform membuat kontainer Docker, lalu Ansible mengonfigurasi aplikasi yang berjalan di dalamnya.
Terraform vs Docker Compose
Untuk lingkungan pengembangan lokal yang sederhana, Docker Compose tetap menjadi pilihan paling pragmatis. Terraform unggul untuk deployment yang dapat direproduksi lintas lingkungan dan ketika diperlukan integrasi dengan komponen infrastruktur lainnya.
Untuk membantu Anda memutuskan mana yang dipilih, saya merangkum perbedaan terpenting dalam tabel ini:
Deployment multi-node kompleks yang memerlukan High Availability.
Komplementer: Terraform mem-provision infrastruktur (cluster), sementara Kubernetes mengelola deployment aplikasi.
Ansible
Manajemen konfigurasi, pemasangan paket, dan penyiapan perangkat lunak.
Mengelola perangkat lunak dan konfigurasi di dalam kontainer.
Komplementer: Terraform membuat kontainer Docker, dan Ansible mengonfigurasi aplikasi yang berjalan di dalamnya.
Docker Compose
Manajemen berbasis proyek yang sederhana dan pragmatis.
Lingkungan pengembangan lokal yang sederhana.
Alternatif: Compose lebih mudah untuk dev lokal, tetapi Terraform lebih baik untuk deployment yang dapat direproduksi lintas lingkungan.
Jika Anda sedang mencari alat pengganti Docker, simak panduan kami tentang alternatif Docker terbaik.
Penutup
Membawa Docker ke dalam manajemen siklus hidup Terraform mengubah deployment kontainer dari prosedur manual menjadi infrastruktur yang dapat direproduksi dan dikendalikan versinya. Dalam tutorial ini, saya menunjukkan cara membangun infrastruktur lengkap selangkah demi selangkah, mulai dari provider dan satu kontainer, lalu secara bertahap menambahkan jaringan, penyimpanan, variabel, modul, dan otomatisasi.
Perbedaan kunci adalah bahwa Terraform menangani provisioning, pembuatan, pembaruan, dan penghancuran resource berdasarkan konfigurasi deklaratif. Orkestrasi penuh dengan penskalaan otomatis dan self-healing memerlukan alat seperti Kubernetes atau Docker Swarm. Terraform dapat mem-provision orkestrator ini, tetapi tidak menggantikannya.
Untuk langkah berikutnya, jelajahi dokumentasi Terraform Registry untuk Docker provider guna menemukan opsi resource tingkat lanjut seperti Docker services untuk Swarm, manajemen secret, dan konfigurasi plugin.
Bagaimana cara mencegah Terraform menghapus image Docker saat menjalankan terraform destroy?⌄
Gunakan parameter keep_locally = true di resource docker_image Anda. Ini memberi tahu Terraform untuk menyimpan image tetap di cache lokal bahkan setelah infrastruktur dihancurkan, yang berguna ketika beberapa kontainer berbagi image yang sama atau saat Anda ingin mempertahankan image yang di-cache antar deployment.
Mengapa Terraform Cloud menampilkan error "Cannot connect to Docker daemon"?⌄
Secara default, Terraform Cloud berjalan dalam mode eksekusi remote, artinya perintah dieksekusi di server Terraform Cloud tempat Docker tidak dapat diakses. Anda harus mengonfigurasi workspace untuk menggunakan mode eksekusi lokal: buka Settings > General > ExecutionMode > Local. Ini menyimpan state secara remote sambil menjalankan perintah Terraform di mesin lokal Anda, tempat Docker dapat diakses.
Bagaimana saya dapat mengelola nilai sensitif seperti kata sandi basis data di Terraform?⌄
Tandai variabel sebagai sensitif menggunakan sensitive = true dalam definisi variabel Anda. Untuk Terraform Cloud, tetapkan variabel sensitif di UI workspace dan tandai sebagai "Sensitive". Untuk eksekusi lokal, gunakan variabel lingkungan dengan prefiks TF_VAR_ (misalnya, export TF_VAR_db_password="password"). Perhatikan bahwa nilainya tetap disimpan sebagai teks biasa di terraform.tfstate, jadi selalu amankan berkas state Anda.
Apa perbedaan antara Terraform dan Docker Compose untuk mengelola kontainer?⌄
Docker Compose mengelola kontainer melalui pendekatan YAML berbasis proyek tanpa memelihara state file. Terraform mencatat setiap resource di terraform.tfstate, memungkinkan deteksi drift antara konfigurasi dan realitas. Terraform unggul untuk deployment yang dapat direproduksi lintas lingkungan dan integrasi dengan infrastruktur lain, sementara Docker Compose lebih sederhana untuk pengembangan lokal. Terraform menyediakan manajemen state yang eksplisit dan kontrol siklus hidup (plan/apply/destroy).
Bagaimana cara memperbarui batas sumber daya kontainer Docker tanpa error?⌄
Walaupun Docker CLI mendukung pembaruan di tempat, Terraform Docker provider sering memaksa penggantian resource untuk memastikan konsistensi state. Untuk menghindari downtime selama penggantian ini, tambahkan blok lifecycle { create_before_destroy = true }. Yang penting, Anda juga harus menghapus argumen name yang tetap (atau gunakan name_prefix) dari definisi resource Anda. Jika Anda mempertahankan nama tetap seperti name = "web-server", kontainer baru akan gagal mulai dengan error "name already in use" sebelum yang lama dihancurkan.
Sebagai Founder Martin Data Solutions serta Data Scientist, ML, dan AI Engineer lepas, saya memiliki portofolio beragam dalam Regression, Classification, NLP, LLM, RAG, Neural Networks, Ensemble Methods, dan Computer Vision.
Berhasil mengembangkan sejumlah proyek ML end-to-end, termasuk pembersihan data, analitik, pemodelan, dan deployment di AWS dan GCP, menghadirkan solusi yang berdampak dan dapat diskalakan.
Membangun aplikasi web yang interaktif dan skalabel menggunakan Streamlit dan Gradio untuk berbagai use case industri.
Mengajar dan membimbing mahasiswa dalam data science dan analitik, mendorong perkembangan profesional mereka melalui pendekatan pembelajaran yang dipersonalisasi.
Merancang konten kursus untuk aplikasi retrieval-augmented generation (RAG) yang disesuaikan dengan kebutuhan enterprise.
Menulis blog teknis AI & ML berdampak tinggi, mencakup topik seperti MLOps, vector database, dan LLM, dengan capaian keterlibatan yang signifikan.
Dalam setiap proyek yang saya tangani, saya memastikan menerapkan praktik terkini dalam rekayasa perangkat lunak dan DevOps, seperti CI/CD, code linting, formatting, pemantauan model, pelacakan eksperimen, dan penanganan error yang tangguh. Saya berkomitmen menyajikan solusi menyeluruh, mengubah wawasan data menjadi strategi praktis yang membantu bisnis bertumbuh dan memaksimalkan pemanfaatan data science, machine learning, dan AI.
Kuasai pertanyaan wawancara basis data, dari konsep SQL dasar hingga skenario desain sistem tingkat lanjut. Panduan mendalam ini mencakup semua yang Anda perlukan untuk sukses di wawancara DBMS dan meraih peran berikutnya.
Temukan alasan mengapa Anda sebaiknya (tidak) menggunakan spaghetti plot untuk menyampaikan ketidakpastian jalur prediksi badai serta dampaknya terhadap interpretasi.
Pelajari kekuatan Docker dan Kubernetes, jalur interaktif ini akan memungkinkan Anda untuk membangun dan mengimplementasikan aplikasi di lingkungan modern.
Saya telah menghabiskan banyak waktu mengelola kontainer Docker secara manual di lingkungan pengembangan dan produksi. Konfigurasi yang tidak selaras, state yang melenceng, dan ketidakpastian apakah setelan lokal saya cocok dengan produksi selalu menghantui tiap deployment. Saat saya menemukan Docker provider milik Terraform, semuanya berubah.
Dalam tutorial ini, saya akan memandu Anda mengintegrasikan Terraform dengan Docker untuk membuat infrastruktur yang dapat direproduksi dan dikendalikan versinya. Anda akan belajar cara mem-provision kontainer, mengelola jaringan dan volume, menerapkan batas sumber daya, serta menjaga state di seluruh tim Anda.
Baik Anda mengelola build server maupun mengorkestrasi microservices, buka terminal Anda dan mari ubah cara Anda menangani infrastruktur Docker.
Jika Anda baru di Docker, saya menyarankan memulai dengan kursus Introduction to Docker kami.
Apa Itu Integrasi Terraform Docker?
Terraform adalah alat infrastructure-as-code yang mengelola siklus hidup sumber daya melalui alur kerja deklaratif. Alih-alih menjalankan perintah Docker satu per satu, Anda mendefinisikan state infrastruktur yang diinginkan di berkas konfigurasi. Terraform kemudian mengeksekusi siklus hidup plan-apply-destroy: menghitung perubahan yang diperlukan, menampilkan pratinjau, dan menerapkannya hanya setelah disetujui.
Provider Terraform Docker berfungsi sebagai lapisan translasi antara kode HashiCorp Configuration Language (HCL) dan Docker API. Saat menulis
resource “docker_container"dalam konfigurasi, provider mengonversi deklarasi tersebut menjadi panggilan Docker API yang sesuai. Abstraksi ini berarti sumber daya Docker dapat dikelola menggunakan alur kerja yang sama seperti untuk infrastruktur cloud.Berikut perbedaan Terraform dari Docker Compose.
Compose mengelola kontainer melalui pendekatan berbasis proyek menggunakan berkas YAML, namun tidak memelihara state file yang melacak apa yang benar-benar ada.
Sebaliknya, Terraform mencatat setiap sumber daya yang dibuatnya di
terraform.tfstate, memungkinkannya mendeteksi drift antara konfigurasi saya dan realitas. Jika seseorang memodifikasi kontainer secara manual, Terraform akan menyadarinya dan dapat mengembalikannya ke state yang didefinisikan.Pendekatan ini unggul dalam beberapa skenario:
Prasyarat dan Instalasi
Sebelum menyelami konfigurasi Terraform, mari verifikasi bahwa alat yang diperlukan telah terpasang dan dikonfigurasi dengan benar.
Memenuhi persyaratan sistem
Pertama, pastikan Docker Engine berjalan di mesin Anda.
Linux: Periksa dengan
docker psmacOS atau Windows: Pastikan Docker Desktop terpasang dan berjalan
Terraform provider membutuhkan akses ke Docker daemon, jadi Anda perlu memastikan pengguna Anda memiliki izin untuk mengakses Unix socket di
/var/run/docker.sockpada Linux atau named pipe di Windows.Selanjutnya, pasang Terraform CLI dari situs resmi HashiCorp. Menginstal Terraform bervariasi menurut sistem operasi:
Linux: Unduh paket yang sesuai atau gunakan manajer paket distribusi Anda.
macOS: Gunakan Homebrew. Pertama, pasang HashiCorp tap dengan
brew tap hashicorp/tap, lalu pasang Terraform dengan perintahbrew install hashicorp/tap/terraform.Windows: Unduh biner dari hashicorp.com dan tambahkan ke PATH Anda, atau gunakan Chocolatey:
choco install terraform.Setelah terpasang, verifikasi instalasi dengan menjalankan
terraform version.Dengan Docker dan Terraform terverifikasi, langkah berikutnya adalah menata berkas proyek agar mudah dipelihara.
Mengonfigurasi struktur proyek
Proyek Terraform diuntungkan dari pendekatan yang jelas dan terstruktur. Biasanya, saya membuat direktori khusus untuk proyek Terraform saya dan menginisialisasi version control:
Version control sangat penting untuk infrastructure-as-code. Setiap perubahan pada infrastruktur Docker harus dilacak, ditinjau, dan dapat dibalik. Biasanya saya menambahkan directory kerja Terraform dan berkas state ke
.gitignoreuntuk mengecualikannya dari version control:Terakhir, saya membuat berkas kosong
main.tftempat saya akan mendefinisikan infrastruktur. Berkas ini akan menampung konfigurasi provider dan definisi resource.Terraform Docker Provider dan Resource Inti
Dengan struktur proyek siap, saatnya mengonfigurasi Docker provider dan mulai mendefinisikan resource.
Menginisialisasi Docker provider
Pertama, dengan menambahkan konfigurasi provider ke
main.tf:Blok
required_providersmenentukan dari mana Terraform harus mengunduh plugin provider. Menggunakan batasan versi (~> 3.0) memungkinkan pembaruan versi minor sekaligus mencegah perubahan yang berpotensi merusak. Untuk host Docker jarak jauh, Anda dapat mengubah parameterhostmenjadi semacamtcp://192.168.1.100:2376.Sekarang jalankan
terraform initdi direktori root proyek. Ini mengunduh plugin Docker provider dan menyimpannya di.terraform/providers/. Perintah ini menampilkan versi tepat yang diinstal, dan Terraform membuat berkas kunci untuk memastikan versi provider konsisten di seluruh tim saya.Mengelola image kontainer
Setelah provider diinisialisasi, langkah berikutnya adalah mendefinisikan image kontainer. Sebelum membuat kontainer, Anda perlu mengelola image yang akan digunakan, jadi Anda perlu mendefinisikan resource image:
Tambahkan resource ini tepat setelah blok provider. Parameter
keep_locallypenting karena mencegah Terraform menghapus image saat saya menjalankanterraform destroy. Ini berguna ketika beberapa kontainer berbagi image yang sama atau saat saya ingin mempertahankan image yang di-cache antar deployment.Untuk deployment produksi, kunci image berdasarkan digest SHA256 untuk memastikan immutability:
Digest dapat diperoleh dari container registry. Untuk image Docker Hub seperti nginx, Anda dapat menemukannya di situs resmi Docker pada bagian Tags. Menggunakan digest menjamin bahwa binary image yang persis sama dideploy setiap saat, bahkan jika seseorang mendorong image baru dengan tag yang sama.
Menyediakan kontainer Docker
Setelah image didefinisikan, langkah berikutnya adalah membuat kontainer yang mereferensikannya:
Image direferensikan menggunakan
docker_image.nginx.image_id. Ini membuat dependensi implisit karena Terraform tidak akan mencoba membuat kontainer sampai image ada. Blokportsmemetakan port internal kontainer 80 ke port 8080 host saya, setara dengandocker run -p 8080:80.Variabel lingkungan diletakkan dalam daftar
envsebagai string. Terraform akan membuat ulang kontainer jika ada parameter yang berubah, memastikan infrastruktur yang berjalan selalu cocok dengan konfigurasi.Pada tahap ini, jalankan
terraform planuntuk melihat apa yang akan dibuat Terraform, laluterraform applyuntuk mem-provision infrastruktur. Terraform akan membuat image dan kontainer. Anda dapat memverifikasinya dengan memeriksa resource di Docker Desktop atau menjalankandocker psdi terminal.Jaringan, Penyimpanan, dan Batas Sumber Daya di Terraform
Sekarang Anda telah menjalankan kontainer dasar dan memahami alur kerja inti, mari perluas infrastruktur dengan fitur siap produksi. Bagian berikut membangun fondasi ini dengan menambahkan jaringan, penyimpanan persisten, dan batasan sumber daya, yang semuanya penting untuk deployment di dunia nyata
Mengelola jaringan
Untuk mengaktifkan komunikasi antar kontainer sambil menjaga isolasi, membuat jaringan khusus sangat penting. Berikut cara membuat jaringan terisolasi untuk mengontrol konektivitas kontainer. Tambahkan resource berikut ke berkas
main.tf:Sekarang tambahkan kontainer kedua yang menggunakan jaringan ini. Tambahkan ini setelah kontainer
web:Ini membuat jaringan bridge khusus dan menautkan kontainer
apike sana. Kontainer pada jaringan yang sama dapat berkomunikasi menggunakan nama kontainer sebagai hostname, yang sangat cocok untuk arsitektur microservices.Verifikasi isolasi jaringan dengan menjalankan
docker network inspect application_netdan memastikan hanya kontainer yang dimaksud yang terhubung. Pastikan Anda menjalankan perintah ini setelah membuat resource menggunakanterraform plandanterraform apply.Dengan jaringan dikonfigurasi untuk komunikasi antar kontainer, aspek penting berikutnya adalah persistensi data.
Mengonfigurasi volume persisten
Untuk data yang harus tetap ada setelah kontainer di-restart, tambahkan resource volume. Sisipkan ini sebelum definisi kontainer:
Sekarang tambahkan kontainer basis data yang menggunakan volume ini:
Volume terkelola seperti ini dibuat dan dikendalikan oleh Docker, disimpan di direktori data Docker. Untuk berbagi berkas konfigurasi dari host, gunakan bind mount dengan menentukan
host_pathalih-alihvolume_name.Setelah memastikan data tetap ada saat kontainer di-restart, sama pentingnya untuk mencegah satu kontainer memonopoli sumber daya sistem.
Menetapkan batas sumber daya
Di luar penyimpanan, mengendalikan seberapa banyak CPU dan memori yang dapat dikonsumsi setiap kontainer sangat penting untuk stabilitas sistem. Untuk mencegah kontainer menggunakan sumber daya berlebihan, terapkan batas sumber daya.
Walaupun Docker memungkinkan pembaruan beberapa batas sumber daya di tempat, model deklaratif Terraform sering kali memerlukan penggantian kontainer untuk memastikan state cocok dengan konfigurasi Anda. Untuk mencegah downtime selama penggantian ini, kita gunakan aturan lifecycle
create_before_destroy.Penting: Kita harus menghapus argumen
nameyang tetap untuk mencegah konflik penamaan selama proses penggantian. Salah satu opsi adalah menggunakan argumenname_prefixsebagai gantinya.Parameter
memorymembatasi RAM dalam megabita. Parametercpu_sharesbekerja berbeda. Ini adalah bobot relatif yang dipakai saat terjadi kontensi CPU. Kontainer dengan 1024 shares akan memperoleh dua kali waktu CPU dibandingkan yang 512 shares, tetapi hanya ketika host berada di bawah beban.Untuk batas CPU yang ketat, Anda juga dapat menggunakan
cpu_setuntuk mem-pin kontainer ke core CPU tertentu:Validasi batas ini dengan menjalankan
docker inspect background-worker --format='{{.HostConfig.Memory}} {{.HostConfig.CpuShares}}dan memeriksa nilai Memory dan NanoCpus sesuai dengan konfigurasi.Sekali lagi, seperti diuraikan di atas, Anda perlu menjalankan
terraform plandanterraform applyterlebih dahulu untuk membuat resource.Pada titik ini, berkas
main.tfberisi konfigurasi provider, satu image, satu jaringan, satu volume, dan tiga kontainer dengan berbagai konfigurasi.Variabel, Modul, dan Rahasia di Terraform
Seiring pertumbuhan infrastruktur, nilai yang di-hardcode menjadi tidak fleksibel. Bagian ini menunjukkan cara membuat konfigurasi dapat digunakan kembali menggunakan variabel, modul, dan penanganan rahasia yang tepat.
Menggunakan variabel input
Langkah pertama untuk membuat konfigurasi fleksibel adalah mengekstrak nilai yang di-hardcode menjadi variabel yang dapat dengan mudah diubah tanpa memodifikasi kode utama. Ini dapat dilakukan dengan membuat berkas baru bernama
variables.tfdi direktori yang sama:Sekarang perbarui kontainer web di
main.tfuntuk menggunakan variabel ini:Blok validasi mencegah penggunaan port berprivilege. Untuk mengganti nilai default, buat berkas
terraform.tfvars:Saat menjalankan
terraform apply, Terraform akan membaca nilai dari berkas ini secara otomatis. Alternatifnya, teruskan nilai melalui baris perintah:terraform apply -var="web_port=9000".Membuat modul yang dapat digunakan kembali
Variabel menyelesaikan masalah nilai yang di-hardcode, tetapi bagaimana jika Anda perlu menerapkan pola lengkap yang sama beberapa kali, lengkap dengan semua resource-nya?
Di sinilah modul unggul. Anggap modul sebagai cetak biru yang menggabungkan semua bagian terpisah itu menjadi satu paket, memungkinkan Anda ‘mencetak’ seluruh setup kompleks tersebut sebagai satu kesatuan.
Mulailah dengan membuat struktur direktori modul:
Sekarang, buat berkas
modules/web-app/variables.tfdan tambahkan hal berikut:Selanjutnya, buat berkas utama
modules/web-app/main.tfdengan resource berikut:Terakhir, buat berkas output
modules/web-app/outputs.tf, yang terutama digunakan untuk menampilkan di terminal nilai yang diinginkan setelah menjalankanterraform apply:Setelah menambahkan definisi modul, jalankan
terraform inituntuk memasang modul, laluterraform applyuntuk membuat kedua kontainer dari templat yang sama. Anda seharusnya dapat melihat semua resource di Docker Desktop.Menangani data sensitif
Nilai sensitif, seperti kata sandi basis data, tidak boleh di-hardcode. Sebagai gantinya, Anda dapat menggunakan berkas
variables.tfdan menetapkansensitive = true:Sekarang perbarui kontainer basis data di
main.tfuntuk mereferensikan kata sandi basis data:Alih-alih menaruh kata sandi di
terraform.tfvarsdan meng-hardcode-nya, tetapkan sebagai variabel lingkungan:Flag
sensitive = truemencegah Terraform menampilkan nilai di output konsol.Namun, nilai-nilai ini disimpan sebagai teks biasa di
terraform.tfstate, jadi untuk memastikan berkas ini aman, kita dapat mengamankannya menggunakan backend jarak jauh dengan enkripsi. Mari jelajahi cara melakukannya.Manajemen State Terraform dan Integrasi CI/CD
Bagian ini membahas mekanisme state dan alur kerja otomatisasi yang penting untuk deployment produksi. Namun sebelum menerapkan otomatisasi, penting untuk memahami bagaimana Terraform melacak infrastruktur Anda melalui berkas state-nya.
Memahami mekanisme state
State adalah fondasi kemampuan Terraform untuk mengelola infrastruktur. Berkas
terraform.tfstatememetakan konfigurasi ke ID kontainer Docker nyata dan atribut resource. Saat menjalankanterraform apply, Terraform membandingkan state ini dengan konfigurasi dan menghitung perubahan minimal yang diperlukan.Periksa state saat ini dengan
terraform show, yang menampilkan setiap resource yang dikelola. Untuk tim, berkas state lokal menimbulkan masalah, konflik, dan potensi kehilangan data. Solusinya adalah backend jarak jauh.Untuk alur kerja berfokus Docker tanpa infra cloudstructure, Terraform Cloud tingkat gratis sangat ideal. Tambahkan blok backend ke bagian
terraformdimain.tf:Buat akun gratis di situs Terraform. Kemudian, jalankan
terraform loginuntuk melakukan autentikasi dengan token yang disediakan, dan laluterraform inituntuk memigrasikan state. Ini menyediakan penguncian state di workspace jarak jauh dan kolaborasi tim tanpa infrastruktur cloud.Namun, Anda juga dapat membuat backend jarak jauh di penyedia Cloud seperti AWS atau GCP.
Mengotomatisasi alur kerja
Dengan manajemen state yang dikonfigurasikan dan disimpan secara jarak jauh, infrastruktur siap untuk kolaborasi tim. Bagian terakhir adalah mengotomatisasi proses deployment melalui pipeline CI/CD, memastikan perubahan yang konsisten dan dapat ditinjau.
Pertama, buat
.github/workflows/terraform.yml:Workflow ini menjalankan
terraform planpada setiap pull request, menampilkan kepada reviewer perubahan infrastruktur apa yang akan terjadi. Saat perubahan digabungkan ke main,terraform applydieksekusi secara otomatis, memastikan setiap perubahan infrastruktur melalui proses tinjauan yang sama seperti perubahan kode.Pemecahan Masalah Terraform Docker
Bahkan dengan konfigurasi yang cermat, masalah bisa muncul. Memahami masalah umum dan kapan mempertimbangkan alternatif membantu membuat keputusan arsitektural yang lebih baik.
“Permission denied”
Kesalahan paling umum di Linux adalah "permission denied" saat menghubungkan ke socket Docker. Ini terjadi ketika pengguna tidak memiliki izin untuk mengakses
/var/run/docker.sock. Perbaiki dengan menambahkan pengguna ke grupdocker:Lalu keluar dan masuk kembali.
Masalah konektivitas WSL2
Di Windows dengan WSL2, masalah konektivitas muncul karena path socket berbeda. Pastikan setelan Docker Desktop "Expose daemon on tcp://localhost:2375 without TLS" diaktifkan, lalu perbarui provider di
main.tf:Kegagalan autentikasi registry privat
Untuk registry Docker privat, tambahkan autentikasi ke blok provider, definisikan kredensial sebagai variabel, dan tetapkan melalui variabel lingkungan untuk menghindari masalah akibat hardcode.
Alternatif untuk Terraform
Di luar pemecahan masalah, sama berharganya untuk memahami kapan alat lain mungkin lebih tepat daripada Terraform untuk kasus penggunaan spesifik Anda.
Terraform vs Kubernetes
Kubernetes menawarkan fitur orkestrasi yang jauh lebih canggih :
Untuk deployment multi-node yang kompleks dengan persyaratan high availability, Kubernetes adalah pilihan yang lebih baik. Terraform dapat mem-provision infrastruktur Kubernetes, sementara Helm atau manifest Kubernetes menangani deployment aplikasi.
Terraform vs Ansible
Ansible unggul dalam manajemen konfigurasi di dalam kontainer. Sementara Terraform mem-provision infrastruktur, Ansible mengelola konfigurasi perangkat lunak dan pemasangan paket. Keduanya sering bekerja bersama: Terraform membuat kontainer Docker, lalu Ansible mengonfigurasi aplikasi yang berjalan di dalamnya.
Terraform vs Docker Compose
Untuk lingkungan pengembangan lokal yang sederhana, Docker Compose tetap menjadi pilihan paling pragmatis. Terraform unggul untuk deployment yang dapat direproduksi lintas lingkungan dan ketika diperlukan integrasi dengan komponen infrastruktur lainnya.
Untuk membantu Anda memutuskan mana yang dipilih, saya merangkum perbedaan terpenting dalam tabel ini:
Alat
Kekuatan Inti
Kasus Penggunaan Terbaik
Perbandingan dengan Terraform
Kubernetes
Orkestrasi canggih (self-healing, penjadwalan lanjutan, load balancing).
Deployment multi-node kompleks yang memerlukan High Availability.
Komplementer: Terraform mem-provision infrastruktur (cluster), sementara Kubernetes mengelola deployment aplikasi.
Ansible
Manajemen konfigurasi, pemasangan paket, dan penyiapan perangkat lunak.
Mengelola perangkat lunak dan konfigurasi di dalam kontainer.
Komplementer: Terraform membuat kontainer Docker, dan Ansible mengonfigurasi aplikasi yang berjalan di dalamnya.
Docker Compose
Manajemen berbasis proyek yang sederhana dan pragmatis.
Lingkungan pengembangan lokal yang sederhana.
Alternatif: Compose lebih mudah untuk dev lokal, tetapi Terraform lebih baik untuk deployment yang dapat direproduksi lintas lingkungan.
Jika Anda sedang mencari alat pengganti Docker, simak panduan kami tentang alternatif Docker terbaik.
Penutup
Membawa Docker ke dalam manajemen siklus hidup Terraform mengubah deployment kontainer dari prosedur manual menjadi infrastruktur yang dapat direproduksi dan dikendalikan versinya. Dalam tutorial ini, saya menunjukkan cara membangun infrastruktur lengkap selangkah demi selangkah, mulai dari provider dan satu kontainer, lalu secara bertahap menambahkan jaringan, penyimpanan, variabel, modul, dan otomatisasi.
Perbedaan kunci adalah bahwa Terraform menangani provisioning, pembuatan, pembaruan, dan penghancuran resource berdasarkan konfigurasi deklaratif. Orkestrasi penuh dengan penskalaan otomatis dan self-healing memerlukan alat seperti Kubernetes atau Docker Swarm. Terraform dapat mem-provision orkestrator ini, tetapi tidak menggantikannya.
Untuk langkah berikutnya, jelajahi dokumentasi Terraform Registry untuk Docker provider guna menemukan opsi resource tingkat lanjut seperti Docker services untuk Swarm, manajemen secret, dan konfigurasi plugin.
Jika Anda ingin mendapatkan pengalaman langsung dengan kontainer, saya merekomendasikan mendaftar di jalur keterampilan interaktif kami Containerization and Virtualization with Docker and Kubernetes.