一千萬個為什麽

搜索

如何測試Terraform配置?



如果您的 Teraform 配置具有適度的復雜性,那麽您如何編寫圍繞配置的測試作為持續集成/持續交付管道的一部分執行?

例如,您可能有一個多雲配置,指定以下所需狀態:

  • 在Azure中托管Docker的Azure容器服務
  • Azure Blob存儲
  • SQL Azure
  • EC2容器服務在AWS中托管Docker
  • Amazon S3存儲服務
  • Amazon RDS SQL Server數據庫

潛在的 terraform apply 可以從頭開始創建上述內容,或者從部分部署狀態轉換為上述所需狀態。

我知道,Terraform將其工作分解為執行計劃階段和應用程序階段,這些階段實際上會更改目標架構。這是否可以用來編寫針對執行計劃的測試,如果有,還有框架來幫助編寫這些測試嗎?

轉載註明原文: 如何測試Terraform配置?

一共有 4 個回答:

目前還沒有完整的解決方案將其集成到Terraform中,但是有一些構建塊可以幫助用單獨的編程語言編寫測試。

Terraform生成JSON格式的狀態文件,原則上可以由外部程序使用,以提取有關Terraform創建的特定數據。雖然這種格式尚未被認為是正式穩定的,但在實踐中,它並不經常變化,以至於人們已經成功地與之整合,並接受在升級Terraform時可能需要做出調整。

這裏采用什麽策略將取決於你想要測試什麽。例如:

  • 在一個正在旋轉虛擬服務器的環境中,像 Serverspec 這樣的工具可以用來運行這些服務器的角度。這可以使用一些帶外過程與Terraform分開運行,也可以作為Terraform的一部分使用 remote-exec provisioner 。這樣可以驗證“服務器是否可以訪問數據庫?”等問題,但不適用於“實例的安全組是否足夠嚴格?”等問題,因為它需要從實例本身之外訪問數據。/p>

  • 可以使用現有的測試框架編寫測試(例如Ruby的RSpec,Python的 unittest 等),它們從Terraform狀態文件中收集相關的資源ID或地址,然後使用相關平臺的SDK檢索有關資源的數據並聲明它們按預期設置。這是前一個想法的更一般的形式,從被測基礎設施的主機外部的角度運行測試,因此可以收集更廣泛的數據集來進行斷言。 p>

  • 為了更加適度的需求,人們可以選擇相信Terraform狀態是對現實的準確表示(在很多情況下是一個有效的假設),並直接在此基礎上作出斷言。這對於簡單的“類似皮棉”的情況來說是最合適的,例如驗證正在遵循正確的資源標記方案以進行成本分配。

相關的Terraform Github問題中有關於此的更多討論。

在最新版本的Terraform中,強烈建議對任何非玩具應用程序使用遠程後端,但這意味著狀態數據不能直接在本地磁盤上使用。但是,可以使用 terraform state pull 命令從遠程後端檢索它的快照,該命令將JSON格式的狀態數據打印到標準輸出,以便可以通過調用程序捕獲和解析它。

作為對這個問題的更新,現在 Kitchen-Terraform 允許測試Terraform配置文件,而不會中斷生產環境。該存儲庫還包含針對不同Terraform提供程序的幾個示例。

我們最近開放源代碼 Terratest ,我們的瑞士軍刀用於測試基礎設施代碼。

今天,您可能會通過部署,驗證和取消部署來手動測試所有基礎架構代碼。 Terratest可幫助您自動執行此過程:

  1. 在Go中編寫測試。
  2. 使用Terratest中的助手來執行真實的IaC工具(例如,Terraform,Packer等)以在真實環境(例如AWS)中部署真實基礎設施(例如服務器)。
  3. 使用Terratest中的助手通過發出HTTP請求,API調用,SSH連接等來驗證基礎結構在該環境中正常工作。
  4. 使用Terratest中的助手在測試結束時取消部署所有內容。

以下是一些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)

這些是集成測試,根據您測試的內容,可能需要5到50分鐘。這並不快(盡管使用 Docker測試階段,你可以加速一些事情),你必須努力使測試可靠,但這是值得的時間。

查看 Terratest repo 獲取文檔和大量的各種類型的基礎設施代碼和相應的測試的例子。

在Aws-Side有 https://github.com/k1LoW/awspec - 應該可以,以terraform.state和測試,whera terraform應用正確。

但我認為,除了低級別的測試工具之外,您還可以考慮考慮如何測試整個基礎架構。

我們在這裏討論這個想法:

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

為了預先測試不變量,我不知道可以使用的解決方案...

我們使用 terraform plan -out = plan.dumpgrep 混合使用了一些實驗,以避免使用元素名稱。這裏有一個關於更易於訪問的計劃格式的討論:github.com/hashicorp/terraform/issues/11883

但目前我們正在為我們基礎設施的重要部分使用手動計劃審核流程。