Terraform プロジェクトでエンド ツー エンドの Terratest テストを実施する

Terraform を使用すると、クラウド インフラストラクチャの定義、プレビュー、およびデプロイを行うことができます。 Terraform を使用する際は、HCL 構文を使って構成ファイルを作成します。 HCL 構文では、Azure などのクラウド プロバイダーと、クラウド インフラストラクチャを構成する要素を指定できます。 構成ファイルを作成したら、"実行プラン" を作成します。これにより、インフラストラクチャの変更をデプロイ前にプレビューすることができます。 変更を確認したら、実行プランを適用してインフラストラクチャをデプロイします。

エンド ツー エンド (E2E) テストは、プログラムを実稼働環境にデプロイする前に動作を検証するために使用されます。 シナリオの例として、2 つの仮想マシンを 1 つの仮想ネットワークにデプロイする Terraform モジュールがあるとします。 2 つのマシンが互いに ping しないようにしたい場合があります。 この例では、デプロイ前に意図した結果を確認するためのテストを定義できます。

E2E テストは通常、3 段階のプロセスです。

  1. 構成をテスト環境に適用します。
  2. コードを実行して結果を確認します。
  3. テスト環境を再初期化または停止します (仮想マシンの割り当て解除など)。

この記事では、次のことについて説明します。

  • Terratest を使用したエンド ツー エンドのテストの基本を理解する
  • Golang を使用してエンド ツー エンド テストを記述する方法について学ぶ
  • コードがリポジトリにコミットされたときに、Azure DevOps を使用して自動的にエンド ツー エンド テストをトリガーする方法を学ぶ

1. 環境を構成する

  • Azure サブスクリプション:Azure サブスクリプションをお持ちでない場合は、開始する前に無料アカウントを作成してください。
  • Go プログラミング言語: Go をインストールします。

  • コード例とリソース: DownGit ツールを使用して、GitHub から end-to-end-testing プロジェクトをダウンロードし、新しいディレクトリにコード例が格納されるように解凍します。 このディレクトリを "サンプル ディレクトリ" と呼びます。

2. エンド ツー エンド テストの概要

エンド ツー エンド テストでは、システムが 1 つのまとまりとして機能しているかどうかを検証します。 この種類のテストは、特定のモジュールのテストとは対照的です。 Terraform プロジェクトの場合、エンド ツー エンド テストによって、何がデプロイ済みであるかを検証できます。 この種類のテストは、デプロイ前のシナリオをテストする他の多くの種類とは異なります。 エンド ツー エンド テストは、複数のモジュールを含み、複数のリソースに作用する複雑なシステムをテストする場合に不可欠です。 このようなシナリオの場合、エンド ツー エンド テストは、さまざまなモジュールが正しく連携しているかどうかを判定する唯一の方法です。

この記事では、Terratest を使用したエンド ツー エンド テストの実装に焦点を当てています。 Terratest は、次のタスクを実行するために必要なすべての機能を備えています。

  • Terraform の構成をデプロイする
  • 何がデプロイ済みであるかを検証するためのテストを、Go 言語を使用して記述できるようにする
  • テストを複数の段階に調整する
  • デプロイされたインフラストラクチャを破棄する

3. テストの例の概要

この記事では、Azure/terraform サンプル リポジトリで入手できるサンプルを使用します。

このサンプルでは、2 つの Linux 仮想マシンを同じ仮想ネットワークにデプロイする Terraform の構成を定義します。 1 つの VM (vm-linux-1 という名前) にはパブリック IP アドレスがあります。 SSH 接続を許可するためにポート 22 だけが開かれています。 2番目の VM (vm-linux-2) には、パブリック IP アドレスは定義されていません。

このテストでは、次のシナリオを検証します。

  • インフラストラクチャが正しくデプロイされている
  • ポート 22 を使用して、vm-linux-1 への SSH セッションを開くことができる
  • vm-linux-1 の SSH セッションを使用して、vm-linux-2 を ping できる

Sample end-to-end test scenario

サンプルをダウンロードした場合、このシナリオの Terraform の構成は src/main.tf ファイルにあります。 main.tf ファイルには、前の図に示されている Azure インフラストラクチャをデプロイするために必要なものがすべて含まれています。

仮想マシンの作成方法を詳しく理解していない場合は、「Terraform を使用して Azure に Linux VM とインフラストラクチャを作成する」を参照してください。

注意事項

この記事に記載されているサンプル シナリオは、例示のみを目的としています。 エンド ツー エンド テストの手順に集中するために、内容を意図的に単純化しています。 運用仮想マシンでパブリック IP アドレスを介して SSH ポートを公開することはお勧めしません。

4. テストの例を調べる

エンド ツー エンド テストは Go 言語で記述し、Terratest フレームワークを使用します。 サンプルをダウンロードした場合、テストは src/test/end2end_test.go ファイルで定義されています。

次のソース コードは、Terratest を使用した Golang テストの標準構造を示しています。

package test

import (
    "testing"

    "github.com/gruntwork-io/terratest/modules/terraform"
    test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
)

func TestEndToEndDeploymentScenario(t *testing.T) {
    t.Parallel()

    fixtureFolder := "../"

    // Use Terratest to deploy the infrastructure
    test_structure.RunTestStage(t, "setup", func() {
        terraformOptions := &terraform.Options{
            // Indicate the directory that contains the Terraform configuration to deploy
            TerraformDir: fixtureFolder,
        }

        // Save options for later test stages
        test_structure.SaveTerraformOptions(t, fixtureFolder, terraformOptions)

        // Triggers the terraform init and terraform apply command
        terraform.InitAndApply(t, terraformOptions)
    })

    test_structure.RunTestStage(t, "validate", func() {
        // run validation checks here
        terraformOptions := test_structure.LoadTerraformOptions(t, fixtureFolder)
		    publicIpAddress := terraform.Output(t, terraformOptions, "public_ip_address")
    })

    // When the test is completed, teardown the infrastructure by calling terraform destroy
    test_structure.RunTestStage(t, "teardown", func() {
        terraformOptions := test_structure.LoadTerraformOptions(t, fixtureFolder)
        terraform.Destroy(t, terraformOptions)
    })
}

前のコード スニペットにあるように、テストは次の 3 つのステージで構成されています。

  • セットアップ: Terraform を実行して構成をデプロイします
  • 検証: 検証チェックとアサーションを行います
  • 破棄: テストの実行後にインフラストラクチャをクリーンアップします

次の一覧は、Terratest フレームワークによって提供される主な関数の一部を示しています。

  • terraform.InitAndApply: Go コードから terraform initterraform apply を実行できるようにします。
  • terraform.Output: デプロイ出力変数の値を取得します。
  • terraform.Destroy: Go コードから terraform destroy コマンドを実行します。
  • test_structure.LoadTerraformOptions: 構成や変数などの Terraform オプションを状態から読み込みます。
  • test_structure.LoadTerraformOptions: 構成や変数などの Terraform オプションを状態から保存します。

5. テストの例を実行する

次の手順では、サンプルの構成とデプロイに対してテストを実行します。

  1. Bash/ターミナル ウィンドウを開きます。

  2. Azure アカウントにログインします。

  3. このサンプル テストを実行するには、ホーム ディレクトリに、SSH 秘密キー/公開キーのペアの名前 id_rsaid_rsa.pub が必要です。 <your_user_name> はホーム ディレクトリの名前に置き換えます。

    export TEST_SSH_KEY_PATH="~/.ssh/id_rsa"
    
  4. サンプル ディレクトリ内で、src/test ディレクトリに移動します。

  5. テストを実行する。

    go test -v ./ -timeout 10m
    

6. 結果を確認する

go test を正しく実行すると、次の出力のような結果が表示されます。

--- PASS: TestEndToEndDeploymentScenario (390.99s)
PASS
ok      test    391.052s

Azure での Terraform のトラブルシューティング

Azure で Terraform を使用する場合の一般的な問題のトラブルシューティング

次のステップ