Terraform vs. CloudFormation: Panduan Definitif
Diterbitkan: 2022-03-11Jika, seperti saya, Anda menjelajahi internet untuk membantu Anda memilih antara CloudFormation dan Terraform sebagai alat infrastruktur-sebagai-kode (IaC) berikutnya tanpa menemukan jawaban yang pasti, saya berbagi rasa sakit Anda untuk waktu yang lama. Sekarang, saya memiliki pengalaman yang signifikan dengan kedua alat dan saya dapat membuat keputusan yang tepat tentang mana yang akan digunakan.
TL;DR
Untuk proyek IaC Anda di AWS, pilih CloudFormation, karena:
- CloudFormation membuat perbedaan antara kode (yaitu, template) dan instantiasi kode (yaitu, tumpukan). Di Terraform, tidak ada perbedaan seperti itu. Lebih lanjut tentang ini di bagian berikutnya.
- Terraform tidak menangani manajemen ketergantungan dasar dengan baik. Lebih lanjut tentang itu di bagian selanjutnya.
Membedakan Antara Kode dan Instansiasi
Satu perbedaan antara CloudFormation dan Terraform adalah bagaimana kode dan instantiasi berhubungan satu sama lain dalam setiap layanan.
CloudFormation memiliki konsep stack , yang merupakan instantiasi dari sebuah template. Kerangka yang sama dapat dipakai tanpa batas oleh klien tertentu dalam akun tertentu, lintas akun, atau oleh klien yang berbeda.
Terraform tidak memiliki konsep seperti itu dan membutuhkan hubungan satu-ke-satu antara kode dan instantiasinya. Ini akan mirip dengan menduplikasi kode sumber server web untuk setiap server yang ingin Anda jalankan, atau menduplikasi kode setiap kali Anda perlu menjalankan aplikasi alih-alih menjalankan versi yang dikompilasi.
Poin ini cukup sepele dalam kasus pengaturan sederhana, tetapi dengan cepat menjadi titik kesulitan utama untuk operasi skala menengah hingga besar. Di Terraform, setiap kali Anda perlu memutar tumpukan baru dari kode yang ada, Anda perlu menduplikasi kode tersebut. Dan menyalin/menempel file skrip adalah cara yang sangat mudah untuk menyabotase diri Anda sendiri dan merusak sumber daya yang tidak ingin Anda sentuh.
Terraform sebenarnya tidak memiliki konsep tumpukan seperti CloudFormation, yang dengan jelas menunjukkan bahwa Terraform telah dibangun dari bawah ke atas untuk memiliki kecocokan satu-ke-satu antara kode dan sumber daya yang dikelolanya. Ini kemudian sebagian diperbaiki oleh konsep lingkungan (yang telah diubah namanya menjadi "ruang kerja"), tetapi cara menggunakannya membuatnya sangat mudah untuk diterapkan ke lingkungan yang tidak diinginkan. Ini karena Anda harus menjalankan terraform workspace select
sebelum menerapkan, dan melupakan langkah ini akan diterapkan ke ruang kerja yang dipilih sebelumnya, yang mungkin atau mungkin bukan yang Anda inginkan.
Dalam praktiknya, memang benar bahwa masalah ini dikurangi dengan penggunaan modul Terraform, tetapi bahkan dalam kasus terbaik, Anda akan memerlukan sejumlah besar kode boilerplate. Faktanya, masalah ini sangat akut sehingga orang perlu membuat alat pembungkus di sekitar Terraform untuk mengatasi masalah ini: Terragrunt.
Manajemen dan Izin Negara
Perbedaan penting lainnya antara CloudFormation dan Terraform adalah bagaimana keduanya mengelola status dan izin.
CloudFormation mengelola status tumpukan untuk Anda dan tidak memberi Anda opsi apa pun. Tetapi status tumpukan CloudFormation telah solid dalam pengalaman saya. Selain itu, CloudFormation memungkinkan pengguna yang kurang beruntung untuk mengelola tumpukan tanpa memiliki semua izin yang diperlukan yang diperlukan oleh tumpukan itu sendiri. Ini karena CloudFormation bisa mendapatkan izin dari peran layanan yang dilampirkan ke tumpukan daripada izin dari pengguna yang menjalankan operasi tumpukan.
Terraform mengharuskan Anda untuk menyediakannya dengan beberapa ujung belakang untuk mengelola status. Standarnya adalah file lokal, yang sama sekali tidak memuaskan, mengingat:
- Kekokohan file status Anda sepenuhnya terkait dengan kekokohan mesin tempat file tersebut disimpan.
- Itu cukup membuat kerja tim menjadi tidak mungkin.
Jadi, Anda memerlukan status yang kuat dan dibagikan, yang pada AWS biasanya dicapai dengan menggunakan bucket S3 untuk menyimpan file status, disertai dengan tabel DynamoDB untuk menangani konkurensi.
Ini berarti Anda perlu membuat bucket S3 dan tabel DynamoDB secara manual untuk setiap tumpukan yang ingin Anda buat instance-nya, dan juga mengelola izin secara manual untuk kedua objek ini guna membatasi pengguna yang kurang memiliki hak istimewa untuk memiliki akses ke data yang seharusnya tidak mereka akses. Jika Anda hanya memiliki beberapa tumpukan, itu tidak akan menjadi masalah, tetapi jika Anda memiliki 20 tumpukan untuk dikelola, itu akan menjadi sangat rumit.
Omong-omong, saat menggunakan ruang kerja Terraform, tidak mungkin memiliki satu tabel DynamoDB per ruang kerja. Ini berarti bahwa jika Anda ingin pengguna IAM dengan izin minimal untuk melakukan penerapan, pengguna tersebut akan dapat mengutak-atik kunci semua ruang kerja karena izin DynamoDB tidak mendetail hingga tingkat item.
Manajemen Ketergantungan
Pada titik ini, CloudFormation dan Terraform bisa sedikit rumit. Jika Anda mengubah ID logis (yaitu, nama) sumber daya, keduanya akan menganggap bahwa sumber daya lama harus dihancurkan dan sumber daya baru dibuat. Jadi biasanya ide yang buruk untuk mengubah ID logis dari sumber daya di salah satu alat, terutama untuk tumpukan bersarang di CloudFormation.
Seperti disebutkan di bagian pertama, Terraform tidak menangani dependensi dasar. Sayangnya, pengembang Terraform tidak memberikan banyak perhatian pada masalah yang sudah berlangsung lama, meskipun tampaknya tidak ada solusi.
Mengingat bahwa manajemen ketergantungan yang tepat sangat penting untuk alat IaC, masalah seperti itu di Terraform mempertanyakan kesesuaiannya segera setelah operasi penting bisnis terlibat, seperti penerapan ke lingkungan produksi. CloudFormation memberikan nuansa yang jauh lebih profesional, dan AWS selalu sangat memperhatikan untuk memastikan bahwa ia menawarkan alat tingkat produksi kepada kliennya. Selama bertahun-tahun saya menggunakan CloudFormation, saya tidak pernah menemukan masalah dengan manajemen ketergantungan.
CloudFormation memungkinkan tumpukan untuk mengekspor beberapa variabel keluarannya, yang kemudian dapat digunakan kembali oleh tumpukan lain. Sejujurnya, fungsi ini terbatas, karena Anda tidak akan dapat membuat instance lebih dari satu tumpukan per wilayah. Ini karena Anda tidak dapat mengekspor dua variabel dengan nama yang sama, dan variabel yang diekspor tidak memiliki ruang nama.
Terraform tidak menawarkan fasilitas seperti itu, jadi Anda memiliki pilihan yang kurang diinginkan. Terraform memungkinkan Anda untuk mengimpor status tumpukan lain, tetapi itu memberi Anda akses ke semua informasi di tumpukan itu, termasuk banyak rahasia yang disimpan di negara bagian. Sebagai alternatif, tumpukan dapat mengekspor beberapa variabel dalam bentuk file JSON yang disimpan dalam ember S3, tetapi sekali lagi, opsi ini lebih rumit: Anda harus memutuskan ember S3 mana yang akan digunakan dan memberikan izin yang sesuai, dan menulis semua kode pipa sendiri di kedua sisi penulis dan pembaca.
Salah satu keunggulan Terraform adalah memiliki sumber data. Terraform dengan demikian dapat menanyakan sumber daya yang tidak dikelola oleh Terraform. Namun, dalam praktiknya, ini memiliki sedikit relevansi ketika Anda ingin menulis template umum karena Anda tidak akan menganggap apa pun tentang akun target. Setara di CloudFormation adalah menambahkan lebih banyak parameter template, yang dengan demikian melibatkan pengulangan dan potensi kesalahan; Namun, dalam pengalaman saya, ini tidak pernah menjadi masalah.
Kembali ke masalah manajemen ketergantungan Terraform, contoh lain adalah Anda mendapatkan kesalahan saat mencoba memperbarui pengaturan untuk penyeimbang beban dan mendapatkan yang berikut:
Error: Error deleting Target Group: ResourceInUse: Target group 'arn:aws:elasticloadbalancing:us-east-1:723207552760:targetgroup/strategy-api-default-us-east-1/14a4277881e84797' is currently in use by a listener or a rule status code: 400, request id: 833d8475-f702-4e01-aa3a-d6fa0a141905
Perilaku yang diharapkan adalah Terraform mendeteksi bahwa grup target adalah ketergantungan dari beberapa sumber daya lain yang tidak dihapus, dan akibatnya, ia tidak boleh mencoba menghapusnya—tetapi juga tidak boleh menimbulkan kesalahan.
Operasi
Meskipun Terraform adalah alat baris perintah, sangat jelas bahwa ia mengharapkan manusia untuk menjalankannya, karena sangat interaktif. Dimungkinkan untuk menjalankannya dalam mode batch (yaitu, dari skrip), tetapi ini memerlukan beberapa argumen baris perintah tambahan. Fakta bahwa Terraform telah dikembangkan untuk dijalankan oleh manusia secara default cukup membingungkan, mengingat tujuan alat IaC adalah otomatisasi.
Terraform sulit untuk di-debug. Pesan kesalahan seringkali sangat mendasar dan tidak memungkinkan Anda untuk memahami apa yang salah, dalam hal ini Anda harus menjalankan Terraform dengan TF_LOG=debug
, yang menghasilkan sejumlah besar keluaran untuk ditelusuri. Rumitnya, Terraform terkadang membuat panggilan API ke AWS yang gagal, tetapi kegagalan tersebut tidak menjadi masalah dengan Terraform. Sebaliknya, CloudFormation memberikan pesan kesalahan yang cukup jelas dengan detail yang cukup untuk memungkinkan Anda memahami di mana masalahnya.
Contoh pesan kesalahan Terraform:
Error: error reading S3 bucket Public Access Block: NoSuchBucket: The specified bucket does not exist status code: 404, request id: 19AAE641F0B4AC7F, host id: rZkgloKqxP2/a2F6BYrrkcJthba/FQM/DaZnj8EQq/5FactUctdREq8L3Xb6DgJmyKcpImipv4s=
Pesan kesalahan di atas menunjukkan pesan kesalahan yang jelas yang sebenarnya tidak mencerminkan masalah mendasar (yang dalam hal ini adalah masalah izin).

Pesan kesalahan ini juga menunjukkan bagaimana Terraform terkadang bisa membuat dirinya terpojok. Misalnya, jika Anda membuat ember S3 dan sumber daya aws_s3_bucket_public_access_block
pada ember itu, dan jika karena alasan tertentu Anda membuat beberapa perubahan pada kode Terraform yang menghancurkan ember itu—misalnya, dalam gotcha “perubahan berarti hapus dan buat” yang dijelaskan di atas— Terraform akan macet saat mencoba memuat aws_s3_bucket_public_access_block
tetapi terus gagal dengan kesalahan di atas. Perilaku yang benar dari Terraform adalah mengganti atau menghapus aws_s3_bucket_public_access_block
sebagaimana mestinya.
Terakhir, Anda tidak dapat menggunakan skrip pembantu CloudFormation dengan Terraform. Ini mungkin menjengkelkan, terutama jika Anda berharap untuk menggunakan cfn-signal, yang memberi tahu CloudFormation bahwa instans EC2 telah selesai menginisialisasi dirinya sendiri dan siap untuk melayani permintaan.
Sintaks, Komunitas, dan Rolling Back
Dari segi sintaks, Terraform memang memiliki keunggulan yang baik dibandingkan dengan CloudFormation—ia mendukung loop. Tapi menurut pengalaman saya sendiri, fitur ini bisa menjadi sedikit berbahaya. Biasanya, sebuah loop akan digunakan untuk membuat sejumlah sumber daya yang identik; namun, saat Anda ingin memperbarui tumpukan dengan hitungan yang berbeda, mungkin ada kemungkinan Anda perlu menautkan sumber daya lama dan baru (misalnya, menggunakan zipmap()
untuk menggabungkan nilai dari dua larik yang sekarang menjadi ukuran yang berbeda karena satu array memiliki ukuran ukuran loop lama dan yang lainnya memiliki ukuran ukuran loop baru). Memang benar bahwa masalah seperti itu dapat terjadi tanpa loop, tetapi tanpa loop, masalahnya akan jauh lebih jelas bagi orang yang menulis skrip. Penggunaan loop dalam kasus seperti itu mengaburkan masalah.
Apakah sintaks Terraform atau sintaks CloudFormation lebih baik sebagian besar merupakan masalah preferensi. CloudFormation awalnya hanya mendukung JSON, tetapi template JSON sangat sulit dibaca. Untungnya, CloudFormation juga mendukung YAML, yang lebih mudah dibaca dan memungkinkan komentar. Namun, sintaks CloudFormation cenderung cukup bertele-tele.
Sintaks Terraform menggunakan HCL, yang merupakan sejenis turunan JSON dan cukup istimewa. Terraform menawarkan lebih banyak fungsi daripada CloudFormation, dan biasanya lebih mudah dipahami. Jadi dapat dikatakan bahwa Terraform memang memiliki sedikit keunggulan dalam hal ini.
Keuntungan lain dari Terraform adalah kumpulan modul yang dikelola komunitas yang tersedia, dan ini menyederhanakan penulisan template. Satu masalah mungkin bahwa modul tersebut mungkin tidak cukup aman untuk memenuhi persyaratan organisasi. Jadi untuk organisasi yang membutuhkan tingkat keamanan yang tinggi, meninjau modul ini (serta versi lebih lanjut yang akan datang) mungkin menjadi kebutuhan.
Secara umum, modul Terraform jauh lebih fleksibel daripada tumpukan bersarang CloudFormation. Tumpukan bersarang CloudFormation cenderung menyembunyikan semua yang ada di bawahnya. Dari tumpukan bersarang, operasi pembaruan akan menunjukkan bahwa tumpukan bersarang akan diperbarui tetapi tidak menunjukkan secara detail apa yang akan terjadi di dalam tumpukan bersarang.
Poin terakhir, yang sebenarnya bisa diperdebatkan, adalah bahwa CloudFormation mencoba untuk mengembalikan penerapan yang gagal. Ini adalah fitur yang cukup menarik tetapi sayangnya bisa sangat lama (misalnya, CloudFormation mungkin memerlukan waktu hingga tiga jam untuk memutuskan bahwa penerapan ke Elastic Container Service telah gagal). Sebaliknya, dalam kasus kegagalan, Terraform hanya berhenti di mana pun itu. Apakah fitur rollback adalah hal yang baik atau tidak masih bisa diperdebatkan, tetapi saya telah menghargai fakta bahwa tumpukan dipertahankan dalam kondisi kerja sebanyak mungkin ketika menunggu lebih lama menjadi tradeoff yang dapat diterima.
Dalam Pertahanan Terraform vs. CloudFormation
Terraform memang memiliki keunggulan dibandingkan CloudFormation. Yang paling penting, menurut saya, adalah ketika menerapkan pembaruan, Terraform menunjukkan kepada Anda semua perubahan yang akan Anda buat, termasuk menelusuri semua modul yang digunakannya. Sebaliknya, CloudFormation, saat menggunakan tumpukan bersarang, hanya menunjukkan kepada Anda bahwa tumpukan bersarang perlu diperbarui, tetapi tidak menyediakan cara untuk menelusuri detailnya. Ini bisa membuat frustasi, karena jenis informasi ini cukup penting untuk diketahui sebelum menekan tombol "pergi".
Ekstensi dukungan CloudFormation dan Terraform. Di CloudFormation, dimungkinkan untuk mengelola apa yang disebut "sumber daya khusus" dengan menggunakan fungsi AWS Lambda dari kreasi Anda sendiri sebagai back end. Untuk Terraform, ekstensi jauh lebih mudah untuk ditulis dan menjadi bagian dari kode. Jadi ada keuntungan bagi Terraform dalam hal ini.
Terraform dapat menangani banyak vendor cloud. Ini menempatkan Terraform pada posisi yang mampu menyatukan penerapan yang diberikan di antara beberapa platform cloud. Misalnya, Anda memiliki satu beban kerja yang tersebar antara AWS dan Google Cloud Platform (GCP). Biasanya, bagian AWS dari beban kerja akan di-deploy menggunakan CloudFormation, dan bagian GCP menggunakan Cloud Deployment Manager GCP. Dengan Terraform, Anda dapat menggunakan satu skrip untuk menerapkan dan mengelola kedua tumpukan di platform cloud masing-masing. Dengan cara ini, Anda hanya perlu menggunakan satu tumpukan, bukan dua.
Non-argumen untuk Terraform vs. CloudFormation
Ada beberapa non-argumen yang terus beredar di internet. Yang terbesar adalah karena Terraform adalah multi-cloud, Anda dapat menggunakan satu alat untuk menyebarkan semua proyek Anda, tidak peduli di platform cloud apa pun proyek tersebut dilakukan. Secara teknis, ini benar, tetapi itu bukan keuntungan besar yang terlihat, terutama ketika mengelola proyek cloud tunggal yang khas. Kenyataannya adalah ada korespondensi hampir satu-ke-satu antara sumber daya yang dideklarasikan di (misalnya) CloudFormation dan sumber daya yang sama yang dideklarasikan dalam skrip Terraform. Karena Anda harus mengetahui detail sumber daya khusus cloud dengan cara apa pun, perbedaannya terletak pada sintaks, yang bukan merupakan titik kesulitan terbesar dalam mengelola penerapan.
Beberapa berpendapat bahwa dengan menggunakan Terraform, seseorang dapat menghindari penguncian vendor. Argumen ini tidak berlaku dalam arti bahwa dengan menggunakan Terraform, Anda dikunci oleh HashiCorp (pencipta Terraform), sama seperti menggunakan CloudFormation, Anda dikunci oleh AWS, dan seterusnya untuk cloud lainnya. platform.
Fakta bahwa modul Terraform lebih mudah digunakan bagi saya tidak terlalu penting. Pertama-tama, saya percaya bahwa AWS sengaja ingin menghindari hosting satu repositori untuk template CloudFormation berbasis komunitas karena tanggung jawab yang dirasakan atas lubang keamanan buatan pengguna dan pelanggaran berbagai program kepatuhan.
Pada tingkat yang lebih pribadi, saya sepenuhnya memahami manfaat menggunakan perpustakaan dalam hal pengembangan perangkat lunak, karena perpustakaan tersebut dapat dengan mudah menjalankan puluhan ribu baris kode. Namun, dalam kasus IaC, ukuran kode biasanya jauh lebih kecil, dan modul semacam itu biasanya panjangnya beberapa lusin baris. Menggunakan salin/tempel sebenarnya bukan ide yang buruk dalam arti menghindari masalah dengan menjaga kompatibilitas dan mendelegasikan keamanan Anda kepada orang yang tidak dikenal.
Menggunakan salin/tempel tidak disukai oleh banyak pengembang dan insinyur DevOps, dan ada alasan bagus di balik ini. Namun, sudut pandang saya adalah bahwa menggunakan salin/tempel untuk potongan kode memungkinkan Anda untuk dengan mudah menyesuaikannya dengan kebutuhan Anda, dan tidak perlu membuat perpustakaan darinya dan menghabiskan banyak waktu untuk membuatnya generik. Kesulitan mempertahankan potongan kode tersebut biasanya sangat rendah, kecuali jika kode Anda menjadi duplikat, katakanlah, selusin atau lebih template. Dalam kasus seperti itu, mengambil kode dan menggunakannya sebagai tumpukan bersarang masuk akal, dan manfaat dari tidak mengulangi diri sendiri mungkin lebih besar daripada gangguan karena tidak dapat melihat apa yang akan diperbarui di dalam tumpukan bersarang saat Anda melakukan pembaruan operasi.
Kesimpulan CloudFormation vs. Terraform
Dengan CloudFormation, AWS ingin memberi pelanggannya alat yang kokoh yang akan berfungsi sebagaimana mestinya setiap saat. Tim Terraform juga, tentu saja—tetapi tampaknya aspek penting dari peralatan mereka, manajemen ketergantungan, sayangnya bukan prioritas.
Terraform mungkin memiliki tempat di proyek Anda, terutama jika Anda memiliki arsitektur multi-cloud, dalam hal ini skrip Terraform adalah salah satu cara untuk menyatukan pengelolaan sumber daya di berbagai vendor cloud yang Anda gunakan. Tetapi Anda masih dapat menghindari kelemahan Terraform dalam kasus ini dengan hanya menggunakan Terraform untuk mengelola tumpukan yang sudah diimplementasikan menggunakan alat IaC khusus cloud masing-masing.
Perasaan keseluruhan Terraform vs. CloudFormation adalah bahwa CloudFormation, meskipun tidak sempurna, lebih profesional dan andal, dan saya pasti akan merekomendasikannya untuk proyek apa pun yang tidak secara khusus multi-cloud.