Bagaimana cara menguji Konfigurasi Terraform?

37

Jika Anda memiliki konfigurasi Terraform yang memiliki tingkat kompleksitas moderat, bagaimana Anda menulis tes di sekitar konfigurasi yang dapat dieksekusi sebagai bagian dari pipeline Integration / Continuous Delivery?

Sebagai contoh, Anda mungkin memiliki konfigurasi multi-cloud yang menentukan kondisi yang diinginkan berikut:

  • Layanan Wadah Azure untuk menjadi tuan rumah Docker di Azure
  • Penyimpanan Azure Blob
  • SQL Azure
  • Layanan Kontainer EC2 untuk menjadi tuan rumah Docker di AWS
  • Layanan Penyimpanan Amazon S3
  • Basis data Amazon RDS SQL Server

Berpotensi terraform applydapat membuat yang di atas dari awal, atau transisi dari keadaan yang dikerahkan sebagian ke keadaan yang diinginkan di atas.

Saya sadar bahwa Terraform membagi pekerjaannya ke dalam tahap rencana eksekusi dan fase aplikasi yang benar-benar membuat perubahan pada arsitektur target. Apakah ini dapat digunakan untuk menulis tes terhadap rencana eksekusi, jika demikian apakah ada kerangka kerja untuk membantu menulis ini?

Richard Slater
sumber
Mungkin berguna: github.com/hashicorp/terraform/issues/5059
Tensibai
Menarik memang, mungkin jawabannya layak.
Richard Slater
Saya tidak menggunakan terraform sendiri, jadi saya membiarkan seseorang dengan pengalaman nyata menulis jawaban :)
Tensibai

Jawaban:

20

Saat ini tidak ada solusi lengkap untuk ini diintegrasikan ke dalam Terraform, tetapi ada beberapa blok bangunan yang dapat berguna untuk membantu dalam menulis tes dalam bahasa pemrograman yang terpisah.

Terraform menghasilkan file status dalam format JSON yang pada prinsipnya dapat digunakan oleh program eksternal untuk mengekstrak data tertentu tentang apa yang dibuat Terraform. Walaupun format ini belum dianggap stabil secara resmi, dalam praktiknya jarang terjadi perubahan sehingga orang berhasil mengintegrasikannya, menerima bahwa mereka mungkin perlu melakukan penyesuaian ketika mereka meningkatkan Terraform.

Strategi apa yang tepat di sini akan sangat tergantung pada apa yang ingin Anda uji. Sebagai contoh:

  • Di lingkungan yang memunculkan server virtual, alat seperti Serverspec dapat digunakan untuk menjalankan tes dari perspektif server ini. Ini dapat dijalankan secara terpisah dari Terraform menggunakan beberapa proses out-of-band, atau sebagai bagian dari Terraform berlaku menggunakan remote-execpenyedia . Ini memungkinkan verifikasi pertanyaan seperti "bisakah server mencapai basis data?", Tetapi tidak cocok untuk pertanyaan seperti "apakah grup keamanan instans cukup ketat?", Karena memeriksa dengan kuat yang memerlukan akses data dari luar instance itu sendiri.

  • Dimungkinkan untuk menulis tes menggunakan kerangka uji yang ada (seperti RSpec untuk Ruby, unittestuntuk Python, dll) yang mengumpulkan id sumber daya yang relevan atau alamat dari file status Terraform dan kemudian menggunakan SDK platform yang relevan untuk mengambil data tentang sumber daya dan menyatakan bahwa mereka diatur seperti yang diharapkan. Ini adalah bentuk yang lebih umum dari ide sebelumnya, menjalankan tes dari perspektif host di luar infrastruktur yang diuji, dan dengan demikian dapat mengumpulkan set data yang lebih luas untuk membuat pernyataan.

  • Untuk kebutuhan yang lebih sederhana, seseorang dapat memilih untuk percaya bahwa keadaan Terraform adalah representasi akurat dari kenyataan (asumsi yang valid dalam banyak kasus) dan hanya menyatakan secara langsung tentang hal itu. Ini paling tepat untuk kasus "mirip-serat" yang sederhana, seperti memverifikasi bahwa skema pemberian tag sumber daya yang benar sedang diikuti untuk tujuan alokasi biaya.

Ada beberapa diskusi lebih lanjut tentang ini dalam masalah Terraform Github yang relevan .

Dalam versi terbaru dari Terraform sangat disarankan untuk menggunakan backend jarak jauh untuk aplikasi non-mainan, tetapi itu berarti bahwa data keadaan tidak langsung tersedia pada disk lokal. Namun, snapshot itu dapat diambil dari backend remote menggunakan terraform state pullperintah, yang mencetak data status yang diformat JSON ke stdout sehingga dapat diambil dan diurai oleh program panggilan.

Martin Atkins
sumber
12

Sebagai pembaruan untuk pertanyaan ini, sekarang ada Kitchen-Terraform yang memungkinkan pengujian file Konfigurasi Terraform tanpa merusak lingkungan produksi. Repositori juga menyertakan beberapa contoh untuk penyedia Terraform yang berbeda.

PrestonM
sumber
12

Kami baru-baru ini membuka Terratest bersumber , pisau tentara swiss kami untuk menguji kode infrastruktur.

Hari ini, Anda mungkin menguji semua kode infrastruktur Anda secara manual dengan menggunakan, memvalidasi, dan menganggur. Terratest membantu Anda mengotomatiskan proses ini:

  1. Tulis tes di Go.
  2. Gunakan bantuan di Terratest untuk mengeksekusi alat IaC nyata Anda (misalnya, Terraform, Packer, dll.) Untuk menggunakan infrastruktur nyata (misalnya, server) di lingkungan nyata (misalnya, AWS).
  3. Gunakan bantuan di Terratest untuk memvalidasi bahwa infrastruktur berfungsi dengan benar di lingkungan itu dengan membuat permintaan HTTP, panggilan API, koneksi SSH, dll.
  4. Gunakan pembantu di Terratest untuk melepas semua pekerjaan di akhir tes.

Berikut ini contoh uji untuk beberapa kode Terraform:

terraformOptions := &terraform.Options {
  // The path to where your Terraform code is located
  TerraformDir: "../examples/terraform-basic-example",
}

// This will run `terraform init` and `terraform apply` and fail the test if there are any errors
terraform.InitAndApply(t, terraformOptions)

// At the end of the test, run `terraform destroy` to clean up any resources that were created
defer terraform.Destroy(t, terraformOptions)

// Run `terraform output` to get the value of an output variable
instanceUrl := terraform.Output(t, terraformOptions, "instance_url")

// Verify that we get back a 200 OK with the expected text
// It can take a minute or so for the Instance to boot up, so retry a few times
expected := "Hello, World"
maxRetries := 15
timeBetweenRetries := 5 * time.Second
http_helper.HttpGetWithRetry(t, instanceUrl, 200, expected, maxRetries, timeBetweenRetries)

Ini adalah tes integrasi, dan tergantung pada apa yang Anda uji, dapat memakan waktu 5 - 50 menit. Itu tidak cepat (meskipun menggunakan Docker dan tahap pengujian , Anda dapat mempercepat beberapa hal), dan Anda harus bekerja untuk membuat tes yang dapat diandalkan, tetapi itu layak waktu.

Lihat repo Terratest untuk dokumen dan banyak contoh berbagai jenis kode infrastruktur dan tes yang sesuai untuk mereka.

Yevgeniy Brikman
sumber
1
Saya juga telah menulis posting blog yang berjalan melalui pengujian salah satu proyek contoh saya dengan Terratest lebih terinci: brightfame.co/blog/… . Mungkin bermanfaat bagi siapa pun. Cheers, Rob!
Rob Morgan
Penggemar Terratest!
jlucktay
7

Selain semua opsi lain yang disebutkan, saya ingin menyebutkan bahwa InSpec 2.0 menambahkan dukungan untuk API penyedia cloud. Pada dasarnya, Anda dapat terus menulis IaC dengan Terraform, lalu menulis cek kepatuhan dengan InSpec untuk sumber daya cloud Anda. Selain itu, InSpec mendukung tes penulisan untuk masing-masing mesin jika Anda membutuhkannya.

Berikut ini adalah artikel dari Christoph Hartmann (co-pencipta Inspec) tentang cara menggunakan Inspec dengan Terraform: https://lollyrock.com/articles/inspec-terraform/

Yekta Leblebici
sumber
5

Di Aws-Side ada https://github.com/k1LoW/awspec - harus dimungkinkan, untuk memberi makan di terraform.state dan menguji, apakah terraform diterapkan dengan benar.

Tapi saya pikir, di luar pengujian pada alat tingkat rendah, Anda menggunakan, mungkin ide yang lebih baik, untuk berpikir tentang bagaimana menguji seluruh infrastruktur.

Kami sedang mendiskusikan ide ini di sini:

https://github.com/DomainDrivenArchitecture/dda-cloudspec/blob/development/README.md

Untuk menguji invarian di muka, saya tidak tahu solusi siap pakai ...

Kami melakukan beberapa percobaan menggunakan campuran terraform plan -out=plan.dumpdan greptanpa adanya nama elemen. Ada diskusi tentang format rencana yang lebih mudah diakses di sini: github.com/hashicorp/terraform/issues/11883

Tetapi saat ini kami sedang menggunakan proses tinjauan rencana manual untuk bagian-bagian penting dari infrastruktur kami.

Jerger
sumber
4
Tujuannya adalah untuk menguji perubahan dalam konfigurasi terraform tidak akan memecah kebutuhan yang diharapkan, begitu dikerahkan sudah terlambat, paling baik Anda gagal melihat DB telah dihapus di tempat yang seharusnya tidak, tetapi Anda telah merusak lingkungan target. .. pertanyaannya adalah tentang menguji kode terraform, bukan menguji hasil akhir, tes unit vs tes integrasi.
Tensibai
good point ... menambahkan bagian untuk menguji invarian.
jerger
0

Saya melihat, metode teknologi ini elegan rendah untuk terraform tes yang disarankan oleh apparentlymart dalam edisi benang GitHub. Ini tidak sesuai untuk setiap situasi tetapi bagus untuk memverifikasi logika modul.

Buat modul root yang mencakup modul yang sedang diuji dan verifikasi output yang diuji. Berikut adalah contoh sederhana menggunakan dua file:

  • main.tf yang akan menjalankan tes
  • simple_module/outputs.tf yang mewakili modul yang sedang diuji

./main.tf

terraform {
  required_version = ">= 0.12"
}

module "simple_module" {
  source = "./simple_module"
}

locals {
  expected = 1
  got      = module.simple_module.module-returns-1
}

# Test Output
output "expect-1" {
  value = upper(local.expected == local.got)
}

output "expect-other" {
  value = "other" == local.got ? upper(true) : "FALSE. Got ${local.got}"
}

./simple_module/outputs.tf

output "module-returns-1" {
  value = 1
}

Jalankan tes

terraform init
terraform apply -auto-approve
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

expect-1 = TRUE
expect-other = FALSE. Got 1
mmell
sumber