Terraform Yapılandırması nasıl test edilir?


37

Orta derecede karmaşıklığa sahip bir Terraform yapılandırmanız olsaydı, bir Sürekli Entegrasyon / Sürekli Teslimat boru hattının bir parçası olarak yapılabilecek konfigürasyona testler nasıl yazardınız?

Örnek olarak, aşağıdaki istenen durumu belirten çoklu bulut yapılandırmasına sahip olabilirsiniz:

  • Azure Container Services, Docker'ı Azure'da ağırlayacak
  • Azure Blob Depolama
  • SQL Azure
  • EC2 Container Service, Docker’ı AWS’de ağırlayacak
  • Amazon S3 Depolama Hizmeti
  • Amazon RDS SQL Server veritabanı

Potansiyel terraform applyolarak yukarıdakileri sıfırdan oluşturabilir veya kısmen dağıtılmış bir durumdan yukarıdaki istenen duruma geçebilir.

Terraform'un çalışmalarını yürütme planı aşamasına ve aslında hedef mimaride değişiklik yapan uygulama aşamasına ayırdığını biliyorum . Bu, yürütme planına karşı testler yazmak için kullanılabilir mi, eğer öyleyse bunları yazmaya yardımcı olacak çerçeveler var mı?



Gerçekten ilginç, muhtemelen layık cevap.
Richard Slater

Terraform'u kendim kullanmıyorum, bu yüzden gerçek tecrübesi olan birinin cevap yazmasına izin
veriyorum

Yanıtlar:


20

Şu anda Terraform'a entegre bunun için tam bir çözüm yoktur, ancak ayrı bir programlama dilinde test yazmanıza yardımcı olacak bazı yapı taşları vardır.

Terraform, JSON formatında, Terraform'un yarattıkları hakkında belirli verileri çıkarmak için harici programlar tarafından kullanılabilecek durum dosyalarını üretir. Bu biçim henüz resmi olarak kararlı sayılmamakla birlikte, pratikte, insanların Terraform'u yükseltirken ayarlamalar yapmaları gerekebileceğini kabul ederek, insanların kendisiyle başarılı bir şekilde bütünleşmeleri için yeterince nadiren değişmektedir.

Burada hangi stratejinin uygun olduğu tam olarak test etmek istediğiniz şeye bağlı olacaktır. Örneğin:

  • Sanal sunucuları bir araya getiren bir ortamda, Serverspec gibi araçlar bu sunucular açısından testleri çalıştırmak için kullanılabilir. Bu ya bazılarını bant süreci kullanılarak Terraform ayrı çalıştırın veya Terraform parçası olarak kullanarak uygulamak edilebilir remote-execProvisioner . Bu, "sunucu veritabanına erişebilir mi?" Gibi soruların doğrulanmasına olanak tanır, ancak örneğin kendi dışından verilere erişmeyi gerektiren sağlam bir şekilde kontrol edilmesinden dolayı "örneğin güvenlik grubu yeterince yetkin midir?" Gibi sorular için uygun değildir.

  • unittestTerraform durum dosyasından ilgili kaynak kimliklerini veya adreslerini toplayan mevcut bir test çerçevesini (Ruby için Pyphon için Ruby, Python, vb.) Kullanarak testler yazmak ve kaynaklarla ilgili verileri almak için ilgili platformun SDK'sını kullanmak ve bunları doğrulamak beklendiği gibi kurulurlar. Bu, önceki fikrin daha genel bir şeklidir; testleri, test edilen altyapının dışındaki bir ev sahibi perspektifinden çalıştırır ve bu nedenle iddialarda bulunmak için daha geniş bir veri kümesi toplayabilir.

  • Daha mütevazı ihtiyaçlar için Terraform devletinin gerçekliğin doğru bir temsili olduğuna (birçok durumda geçerli bir varsayım olduğuna) güvenmeyi seçebilir ve doğrudan doğrudan iddiaya girebilirsiniz. Bu, maliyet tahsisatı amacıyla doğru kaynak etiketleme planının izlendiğini doğrulamak gibi basit "tiftik benzeri" durumlar için uygundur.

Bununla ilgili Terraform Github sayısında daha fazla tartışma var .

Terraform'un en son sürümlerinde, oyuncak olmayan herhangi bir uygulama için uzak bir arka uç kullanılması şiddetle tavsiye edilir, ancak bu durum verilerinin doğrudan yerel diskte bulunmadığı anlamına gelir. Bununla birlikte, terraform state pullJSON formatlı durum verilerini stdout'a basan komut kullanılarak uzaktan arka uçtan bir anlık görüntü alınabilir, böylece çağrı yapan bir program tarafından yakalanıp ayrıştırılabilir.


12

Bu sorunun bir güncellemesi olarak, artık Terraform Konfigürasyon dosyalarının üretim ortamlarını bozmadan test edilmesini sağlayan Kitchen-Terraform var. Depo ayrıca farklı Terraform sağlayıcıları için birkaç örnek içerir.


12

Yakın zamanda altyapı kodunu test etmek için İsviçre çakısı kaynaklı Terratest'i açtık .

Bugün, muhtemelen tüm altyapı kodunuzu manuel olarak test ederek, doğrulayarak ve geri alarak test ediyoruz. Terratest, bu işlemi otomatikleştirmenize yardımcı olur:

  1. Go'da testler yaz.
  2. Gerçek altyapıyı (örneğin sunucular) gerçek bir ortamda (örn. AWS) dağıtmak için gerçek IaC araçlarınızı (örneğin, Terraform, Packer, vb.) Çalıştırmak için Terratest'teki yardımcıları kullanın.
  3. HTTP istekleri, API çağrıları, SSH bağlantıları vb. Yaparak altyapının bu ortamda doğru çalıştığını doğrulamak için Terratest'teki yardımcıları kullanın.
  4. Testin sonunda her şeyi dağıtmak için Terratest'teki yardımcıları kullanın.

İşte bazı Terraform kodu için bir örnek test:

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)

Bunlar entegrasyon testleridir ve ne test ettiğinize bağlı olarak 5 - 50 dakika sürebilir. Hızlı değil ( Docker ve test aşamalarını kullanıyor olsanız da, bazı şeyleri hızlandırabilirsiniz) ve testleri güvenilir hale getirmek için çalışmanız gerekecek, ancak zaman ayırmaya değer.

Check out Terratest repo dokümanlar ve altyapı kod çeşitli örnekler sürü ve bunlara karşılık gelen testler için.


1
Ayrıca örnek projelerimden birini Terratest ile daha ayrıntılı olarak test eden bir blog yazısı yazdım: brightfame.co/blog/… . Bu herkes için değerli olabilir. Şerefe, Rob!
Rob Morgan

Terratest'in büyük hayranı!
jlucktay

7

Belirtilen diğer tüm seçeneklere ek olarak, InSpec 2.0'ın bulut sağlayıcı API'leri için destek eklediğini belirtmek isterim. Temel olarak, IaC'yi Terraform ile yazmaya devam edebilir, daha sonra bulut kaynaklarınız için InSpec ile uyumluluk kontrolleri yazabilirsiniz. Ek olarak, InSpec ihtiyaç duyduğunuzda bireysel makineler için test yazmayı da destekler.

Christoph Hartmann'dan (Inspec'in yaratıcısı) Inspec'in Terraform ile nasıl kullanılacağı hakkında bir makale: https://lollyrock.com/articles/inspec-terraform/


5

Aws-Side'de https://github.com/k1LoW/awspec vardır - terraform.state içinde besleme ve terraform doğru uygulandığında test etmek mümkün olmalıdır.

Ancak bence, düşük seviyede test etmenin ötesinde, tüm altyapıların nasıl test edileceği hakkında düşünmek muhtemelen daha iyi bir fikirdir.

Burada bu fikri tartışıyoruz:

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

Değişmeyenleri önceden test etmek için, kullanıma hazır bir çözüm bilmiyorum.

Eleman adlarının bir karışımı terraform plan -out=plan.dumpve grepyokluğunu kullanarak bazı deneyler yaptık . Burada daha erişilebilir bir plan formatı hakkında bir tartışma var: github.com/hashicorp/terraform/issues/11883

Ancak şu anda altyapımızın önemli bölümleri için bir el ile değerlendirme planı kullanıyoruz.


4
Amaç, terraform yapılandırmasındaki değişiklikleri test etmek, beklenen ihtiyaçları karşılamayacak, dağıtıldıktan sonra çok geç, en iyi ihtimalle bir DB'nin kaldırılmaması gereken yerin kaldırıldığını, ancak hedef ortamı bozduğunuzu görmediniz. .. soru terraform kodunu test etmektir, sonuçta test değil, birim testleri ve entegrasyon testleri.
Tensibai

iyi nokta ... değişmezleri test etmek için bir bölüm ekledi.
birleşme

0

GitHub sayısında görünüşte öne sürülen Terraform'u test etmek için bu zarif, düşük teknolojili yöntemi gördüm . Her durum için uygun değildir ancak modül mantığını doğrulamak için harikadır.

Test edilen modülü içeren ve test dışı çıktıları doğrulayan bir kök modül oluşturun. İki dosyayı kullanarak basit bir örnek:

  • main.tf testleri yapacak
  • simple_module/outputs.tf test edilen bir modülü temsil eder

./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
}

Testleri çalıştırın

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

Outputs:

expect-1 = TRUE
expect-other = FALSE. Got 1
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.