Azure で Terraform プロジェクトの統合テストを実装する

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

統合テストでは、新しく導入されたコード変更によって既存のコードが破損しないことが検証されます。 DevOps の場合、継続的インテグレーション (CI) とは、コード ベースが変更される (たとえば、PR を Git リポジトリにマージしようとする) たびにシステム全体を構築するプロセスを指します。 次の一覧には、統合テストの一般的な例が含まれています。

  • lint や format などの静的コード分析ツール。
  • terraform validate を実行して、構成ファイルの構文を検証します。
  • terraform plan を実行して、構成が想定どおりに機能することを確認します。

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

  • Terraform プロジェクトの統合テストの基本について学びます。
  • Azure DevOps を使用して継続的インテグレーション パイプラインを構成します。
  • Terraform コードに対する静的コード分析を実行します。
  • terraform validate を実行して、ローカル コンピューター上の Terraform 構成ファイルを検証します。
  • terraform plan を実行して、リモート サービスの観点からその Terraform 構成ファイルを検証します。
  • Azure パイプラインを使用して継続的インテグレーションを自動化します。

1. 環境を構成する

  • Azure サブスクリプション:Azure サブスクリプションをお持ちでない場合は、開始する前に 無料アカウント を作成してください。

2. ローカルの Terraform の構成を検証する

terraform validate コマンドは、Terraform ファイルが格納されているディレクトリでコマンド ラインから実行します。 このコマンドの主な目的は、構文の検証です。

  1. サンプル ディレクトリ内で、src ディレクトリに移動します。

  2. terraform init を実行して、作業ディレクトリを初期化します。

    terraform init
    
  3. terraform validate を実行して、構成ファイルの構文を検証します。

    terraform validate
    

    重要なポイント:

    • Terraform の構成が有効であることを示すメッセージが表示されます。
  4. main.tf ファイルを編集します。

  5. 5 行目に入力ミスを挿入して、構文を無効にします。 たとえば、var.locationvar.loaction に置き換えます。

  6. ファイルを保存します。

  7. 検証をもう一度実行します。

    terraform validate
    

    重要なポイント:

    • エラーのコード行とエラーの説明を示すエラー メッセージが表示されます。

ご覧のように、Terraform によって構成コードの構文の問題が検出されました。 この問題が原因で、構成をデプロイできません。

Terraform ファイルをバージョン管理システムにプッシュする前に、それに対して terraform validate を常に実行することをお勧めします。 また、このレベルの検証は、継続的インテグレーション パイプラインの一部として行う必要があります。 この記事の後半では、自動的に検証するように Azure パイプラインを構成する方法について説明します。

3. Terraform の構成を検証する

前のセクションでは、Terraform の構成を検証する方法を確認しました。 このレベルのテストは、構文のみに対するものです。 そのテストでは、既に Azure にデプロイされているものは考慮されませんでした。

Terraform は "宣言型言語" です。つまり、最終的な結果として何が必要かを宣言します。 たとえば、1 つのリソース グループに 10 台の仮想マシンがあるとします。 この場合に、3 つの仮想マシンを定義する Terraform ファイルを作成します。 このプランを適用しても、合計数は 13 に増えません。 代わりに、Terraform によって仮想マシンのうちの 7 台が削除され、最終的に 3 台になります。 terraform plan を実行すると、実行プランを適用したときの想定される結果を確認し、想定外の事態を避けることができます。

Terraform の実行プランを生成するには、terraform plan を実行します。 このコマンドは、ターゲットの Azure サブスクリプションに接続して、構成のどの部分が既にデプロイされているかを確認します。 その後、Terraform によって、Terraform ファイルに記載されている要件を満たすために必要な変更が 特定されます。 この段階では、Terraform によって何もデプロイされていません。 プランを適用した場合に何が生じるかが示されます。

記事に従って前のセクションの手順を完了している場合は、terraform plan コマンドを実行します。

terraform plan

terraform plan を実行すると、実行プランを適用した場合に想定される結果が Terraform によって表示されます。 出力には、追加、変更、破棄される Azure リソースが示されます。

既定では、Terraform により、Terraform ファイルと同じローカル ディレクトリに状態が格納されます。 このパターンは、シングル ユーザーのシナリオに適しています。 ただし、複数のユーザーが同じ Azure リソースで作業すると、ローカル状態ファイルが同期から外れる可能性があります。この問題を解決するために、Terraform では、リモート データ ストア (Azure Storage など) への状態ファイルの書き込みがサポートされています。 このシナリオでは、terraform plan をローカル コンピューターで実行し、リモート マシンをターゲットにすると問題が発生する可能性があります。 そのため、この検証ステップを継続的インテグレーション パイプラインの一環として自動化することが適切であると考えられます。

4. 静的コード分析を実行する

静的コード分析は Terraform 構成コードで直接実施でき、それを実行する必要はありません。 この分析は、セキュリティの問題やコンプライアンスの不整合などの問題の検出に役立ちます。

次のツールによって、Terraform ファイルの静的分析を行うことができます。

静的分析は、多くの場合、継続的インテグレーション パイプラインの一環として実行されます。 これらのテストでは、実行プランまたはデプロイを作成する必要ありません。 そのため、これらは他のテストより短時間で実行され、通常は継続的インテグレーション プロセスで最初に実行されます。

5. Azure パイプラインを使用して統合テストを自動化する

継続的インテグレーションには、変更の導入時におけるシステム全体のテストが含まれています。 このセクションでは、継続的インテグレーションの実装に使用される Azure パイプラインの構成について説明します。

  1. 任意のエディターを使用して、GitHub の Terraform サンプル プロジェクトのローカルの複製を参照します。

  2. samples/integration-testing/src/azure-pipeline.yaml ファイルを開きます。

  3. steps セクションまで下方向にスクロールすると、さまざまなインストールと検証ルーチンの実行に使用される標準的なステップのセットが表示されます。

  4. Step 1: run the Checkov Static Code Analysis という行を確認します。 このステップでは、前に説明した Checkov プロジェクトで、サンプルの Terraform の構成に対して静的コード分析を実行します。

    - bash: $(terraformWorkingDirectory)/checkov.sh $(terraformWorkingDirectory)
      displayName: Checkov Static Code Analysis
    

    重要なポイント:

    • このスクリプトによって、Docker コンテナー内にマウントされた Terraform ワークスペースで Checkov が実行されます。 Microsoft が管理するエージェントでは Docker が有効になっています。 Docker コンテナー内でツールを実行する方が簡単であり、Azure パイプライン エージェントに Checkov をインストールする必要がなくなります。
    • $(terraformWorkingDirectory) 変数は、azure-pipeline.yaml ファイルで定義されています。
  5. Step 2: install Terraform on the Azure Pipelines agent という行を確認します。 前にインストールした Terraform の Build & Release Task 拡張機能には、Azure パイプラインを実行しているエージェントに Terraform をインストールするためのコマンドがあります。 このタスクは、このステップで実行されているものです。

    - task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-installer.TerraformInstaller@0
      displayName: 'Install Terraform'
      inputs:
        terraformVersion: $(terraformVersion)
    

    重要なポイント:

    • インストールする Terraform のバージョンは、terraformVersion という名前の Azure パイプライン変数を使用して指定し、azure-pipeline.yaml ファイルで定義します。
  6. Step 3: run Terraform init to initialize the workspace という行を確認します。 Terraform がエージェントにインストールされたので、Terraform ディレクトリを初期化できます。

    - task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-cli.TerraformCLI@0
      displayName: 'Run terraform init'
      inputs:
        command: init
        workingDirectory: $(terraformWorkingDirectory)
    

    重要なポイント:

    • command の入力では、実行する Terraform コマンドを指定します。
    • workingDirectory の入力は、Terraform ディレクトリのパスを示します。
    • $(terraformWorkingDirectory) 変数は、azure-pipeline.yaml ファイルで定義されています。
  7. Step 4: run Terraform validate to validate HCL syntax という行を確認します。 プロジェクト ディレクトリが初期化されると、サーバーの構成を検証するために terraform validate が実行されます。

    - task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-cli.TerraformCLI@0
      displayName: 'Run terraform validate'
      inputs:
        command: validate
        workingDirectory: $(terraformWorkingDirectory)
    
  8. Step 5: run Terraform plan to validate HCL syntax という行を確認します。 先ほど説明したように、実行プランの生成は、デプロイ前に Terraform の構成が有効かどうかを確認するために行います。

    - task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-cli.TerraformCLI@0
      displayName: 'Run terraform plan'
      inputs:
        command: plan
        workingDirectory: $(terraformWorkingDirectory)
        environmentServiceName: $(serviceConnection)
        commandOptions: -var location=$(azureLocation)
    

    重要なポイント:

    • environmentServiceName の入力は、「環境を構成する」で作成された Azure サービスの接続の名前を示します。 この接続を使用して、Terraform がユーザーの Azure サブスクリプションにアクセスできます。
    • commandOptions の入力は、Terraform コマンドに引数を渡すために使用されます。 この場合、場所が指定されています。 $(azureLocation) 変数は、前に YAML ファイルで定義されています。

Azure DevOps にパイプラインをインポートする

  1. Azure DevOps プロジェクトを開き、Azure Pipelines のセクションに進みます。

  2. [パイプラインを作成] ボタンを選択します。

  3. [コードはどこにありますか?] オプションで、[GitHub (YAML)] を選択します。

    コードはどこにありますか?

  4. この時点で、Azure DevOps に、ご自身の組織へのアクセスを承認することが必要になる可能性があります。 このトピックの詳細については、記事「GitHub リポジトリの構築」を参照してください。

  5. リポジトリの一覧で、GitHub 組織で作成したリポジトリのフォークを選択します。

  6. [パイプラインを構成する] ステップで、既存の YAML パイプラインから開始することを選択します。

    既存の YAML パイプライン

  7. [Select existing YAML pipeline]\(既存の YAML パイプラインを選択する\) ページが表示されたら、ブランチ master を指定し、YAML パイプラインへのパス (samples/integration-testing/src/azure-pipeline.yaml) を入力します。

    既存の YAML パイプラインを選択する

  8. [続ける] を選択して、GitHub から Azure YAML パイプラインを読み込みます。

  9. [パイプライン YAML をレビューする] ページが表示されたら、[実行] を選択して、初めてパイプラインを作成し、手動でトリガーします。

    Azure パイプラインを実行する

結果を確認する

パイプラインは Azure DevOps UI から手動で実行できます。 ただし、この記事の要点は、自動化された継続的インテグレーションを示すことです。 フォークされたリポジトリの samples/integration-testing/src フォルダーへの変更をコミットして、プロセスをテストします。 この変更により、コードをプッシュしているブランチで新しいパイプラインが自動的にトリガーされるようになります。

GitHub から実行中のパイプライン

このステップが完了したら、Azure DevOps の詳細にアクセスして、すべてが正しく実行されていることを確認します。

Azure DevOps の緑色のパイプライン

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

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

次のステップ