web-dev-qa-db-ja.com

Terraformファイルをテストする方法

Terraformファイルでインフラストラクチャを定義しています。 Terraformは大好きですが、テスト方法がわかりません。私はawspecを持っています。これは本当に素晴らしく、AWSAPIを介したビルドの結果に対してRSpecのようなテストを実行します。しかし、terraform planの結果のように、単体テストを行う方法はありますか?他の人がTerraformで使用しているワークフローはどのようなものですか?

5
David Ham

キッチン-テラフォームの詳細については、Beginの回答をさらに詳しく説明します。

Kitchen-Terraform は、 Test-Kitchen 内で実行されるオープンソースプラグインのセットです。これらは、Terraformモジュールリポジトリに移動して、で使用される前にそのモジュールの機能をテストすることになっています。リソースを作成するリポジトリ。詳細については、これら2つのプロジェクトのドキュメントを自由に確認してください。ただし、Terraformコードの統合テストに関する推奨事項を確認します。

Ruby、Terraformをインストールするこの例では、Terraformモジュールリポジトリは次のように呼び出されます。my_terraform_module

mkdir -p my_terraform_module
cd my_terraform_module

mkdir -p test/integration/kt_suite/controls \
         test/fixtures/tf_module/

Gemfileを作成します:

source "https://rubygems.org/" do
  gem "kitchen-terraform"
end

必要なコンポーネントをインストールします(kitchen-terraformの依存関係にGemfileを使用します)

gem install bundler
bundle install

Test-Kitchenファイルを作成します.kitchen.yml-これにより、テストフレーム、Test-KitchenとKitchen-Terraformが統合されます。

---
driver:
  name: terraform
  root_module_directory: test/fixtures/tf_module
  parallelism: 4

provisioner:
  name: terraform

transport:
  name: ssh

verifier:
  name: terraform
  groups:
    - name: basic
      controls:
        - file_check
        - state_file

platforms:
  - name: terraform

suites:
  - name: kt_suite

Terraformコードは、次のようなTerraformモジュールリポジトリのルートにある必要があります。

my_terraform_module/
  |-- main.tf

main.tfに入れることができるサンプルコード

resource "null_resource" "create_file" {
  provisioner "local-exec" {
    command = "echo 'this is my first test' > foobar"
  }
}

次に、 Terraform live repos -と同じようにTerraformモジュールを参照しますが、代わりにこのファイルのテストフィクスチャで参照します:test/fixtures/tf_module/main.tf

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

次に、そこからTerraform applyを実行できますが、Kitchen-TerraformとTest-Kitchenでは少し異なる方法で実行され、状態と他のいくつかの項目を追跡するのに役立つ収束を実行します。

bundle exec kitchen converge

Terraformコードが適用されるのを確認したので、テストする必要があります。統合テストのように作成された実際のリソースをテストできますが、セミユニットテストである状態ファイルをテストすることもできますが、現在HCLに対してユニットテストを実行できるものは何も知りません。 Terraformのコード。

Inspecのデフォルトプロファイルファイルを作成します:test/integration/kt_suite/inspec.yml

---
name: default

統合テスト用のInspecコントロールを作成します。test/integration/kt_suite/controls/basic.rb-以前にmain.tfに使用したTerraformコードの例のテストを使用しています。

# frozen_string_literal: true

control "file_check" do
  describe file('.kitchen/kitchen-terraform/kt-suite-terraform/foobar') do
    it { should exist }
  end
end

これは、状態ファイルから情報を取得し、そこに何かが存在するかどうかをテストするテストの例です。これは基本的なものですが、この例を拡張することは間違いありません。

# frozen_string_literal: true

terraform_state = attribute "terraform_state", {}

control "state_file" do
  describe "the Terraform state file" do
    subject do json(terraform_state).terraform_version end

    it "is accessible" do is_expected.to match /\d+\.\d+\.\d+/ end
  end
end

次に、Test-KitchenおよびKitchen-Terraformを使用してInspecコントロールを実行します。

bundle exec kitchen verify

スタートガイドとここにあるチュートリアルのいくつかからこれをたくさん取り入れました: https://newcontext-oss.github.io/kitchen-terraform/getting_started.html

5
nictrix

最近、インフラストラクチャコードをテストするためのスイスアーミーナイフである 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 で、さまざまなタイプのインフラストラクチャコードのドキュメントと多くの例、およびそれらに対応するテストを確認してください。

7

私の調査によると、これは難しい問題です。Terraformはフル機能のプログラミング言語を意図したものではなく、Terraformで必要なリソースを宣言しているのであり、それらを構築する方法ではなく、単体テストを試みても実際には得られません。実際に適用を実行せずに、希望する方法でリソースを構築していることを保証します。これにより、ユニットテストの試みは私にとっては糸くずのように感じられます。

ただし、HCLファイルを pyhcl のようなもので解析したり、計画ファイルを解析したりすることはできますが、私の経験から、これはほとんどメリットがないために多くの作業でした(ただし、より簡単な方法がない可能性があります) !)。

テラフォームの結果をテストしたい場合のいくつかの選択肢は次のとおりです。

kitchen-terraform は書き込み用のツールです Test Kitchen インフラストラクチャの仕様。

kitchen-verifier-awspecawspeckitchen-terraformをまとめるのに役立ちますが、個人的には使用していません。

AWSを使用している場合、 AWS Config は、セットアップやメンテナンスをあまり行わなくても、他のインフラストラクチャテストツールと同じ多くのメリットを提供できることがわかりました。それはかなり新しいですが、私はそれを広く使用していません。

また、 Terraform Premium にアクセスできる場合は、 Sentinel にアクセスできます。これは、AWS Configと同様のメリットを数多く提供しているようですが、個人的には使用していません。

2
Begin

1つの方法は、-out=tempfileを使用して結果をファイルに出力し、スクリプトを実行して実行しようとしていることを検証し、すべてが合格した場合はファイルを適用コマンドに渡すことです。ここで-outを見てください: https://www.terraform.io/docs/commands/plan.html

0
Moe

Github.com/palantir/tfjsonを使用して、.planファイルをjsonに解析できます。

現時点では、"不明なプランファイルのバージョン:2"エラーが発生する問題があります。これは、ベンダーバージョンのterraformが古すぎるためです。

修正は次のとおりです。

go get github.com/palantir/tfjson
cd $GOPATH/src/github.com/palantir/tfjson
rm -rf vendor
go get -v ./...

その後、../../hashicorp/terraform/config/testing.goにエラーがあります。修正するには、行を変更するだけです

t.Helper()

//t.Helper()

もう一度go getを実行してから、go installを実行します

go get -v ./...
go install ./...

これで、json出力を生成する次のことができるようになります。

terraform plan --out=terraform.plan 
tfjson terraform.plan
0
Tim Hughes