Terraformを効果的にテストする
Peter De Tender
2022年8月2日
0 分で読めますTerraformは、DevOpsチームがコーディングの概念を活用して、オンプレミスまたはパブリッククラウドのインフラストラクチャコンポーネントを自動的にデプロイできるIaC(Infrastructure as Code)ソリューションです。対象となるコンポーネントには、仮想マシン、ネットワークコンポーネント、ストレージ、アプリケーション、データベースサービスなどがあります。
TerraformではHashiCorp Language(HCL)を使用します。HCLは統一されたドメイン固有言語で、Amazon AWS CloudFormation、Microsoft Azure ARM TemplatesやBicep、Google Cloud Deployment Manager for GCPなど、さまざまなクラウドプロバイダー向けのテンプレート作成を効率化します。
コードのテストがソフトウェア開発に欠かせないのと同様に、TerraformのようなIaCソリューションのテストも重要です。適切に組み込まれたIaCテストは、リソース管理に関する重大な問題を軽減し、DevOpsチームが構成の有効性を検証できるようにします。
ただし、このテストをDevOpsプロセスに組み込むのは容易ではありません。テストに何を含めるべきか、何を省略できるのか、利用可能な仕組みのうちどれが最も効果的なのかといった疑問が生じます。
Terraformテンプレートのテストには、さまざまな方法があります。terraform validateやterraform planなど、Terraformに組み込まれたコマンドを使うのが最も簡単です。これらのコマンドを使えば、単体テスト、統合テスト、コンプライアンステスト、エンドツーエンドテストを作成でき、従来のソフトウェア開発におけるテスト手法にもよく適合します。別の方法として、Cloud Development Kit for Terraform(CDKTF)を使った、より開発者向けのアプローチもあります。
最終的には、DevOpsチームが検証プロセスの目標を明確にする必要があります。テンプレートの構文確認や、テンプレートのデプロイが成功することの確認が目標となる場合もあります。また、セキュリティの問題や設定ミスを重点的にテストし、デプロイ実行時のセキュリティへの影響を検出する、より高度なテストシナリオを構築することが目標となる場合もあります。重要なのは、何をテストすべきかを正確に把握し、適切なテストソリューションを組み合わせることです。
Terraformのテスト戦略
Terraformで使えるさまざまなテスト戦略を見ていきましょう。
ドリフトテスト
Terraformはterraform stateファイルを使って、現在のインフラストラクチャを検証します。Terraformのデプロイが実行されるたびに、最終状態がstateファイルに書き込まれます。このファイルは通常、共有場所に保存されます。
ただし、対象環境へのデプロイがすべてTerraformから実行されているとは限りません。その場合、「実際の」リソースと、Terraformのstateファイルが稼働中だと認識しているリソースとの間に差異が生じることがあります。このデプロイがTerraformで管理されているリソースに影響する場合、組み込みコマンドterraform planが役立ちます。stateファイルの管理対象と実際の対象環境との変更や差異を検出できるためです。一方、デプロイによってまったく新しいリソースが作成される場合は、driftctlやCloudQueryなどのツールが役立ちます。Terraformの管理下にないすべてのリソースを報告できます。
単体テスト
単体テストは、最も簡単に実施できるテストのひとつです。通常は個々のオブジェクトを対象に、具体的で比較的基本的なテストを実行します。テンプレートの構文が正しいことの検証も、よく行われるテストです。
この場合はterraform validateを使用できます。テンプレートの構文に誤りがあると、terraform validateはエラーメッセージを返します(構文エラーが正しく検出されたとしても、デプロイの成功が保証されるわけではありません)。
デプロイを検証するには、もうひとつの組み込みコマンドterraform planを利用できます。planフェーズを実行すると、Terraformが実際のデプロイをシミュレーションし、プロバイダーのバックエンドと通信して、terraform applyコマンドによるデプロイの結果を報告します。
terraform planの出力を確認すると、既存の環境に対して検出された変更がわかります。これには、新しいリソースの作成、変更、削除が含まれることがあります。この情報を活用すれば、DevOpsチームはデプロイを実行する前に、その影響を把握できます。
次のステップではTerraform applyを使い、実際のデプロイを実行します。ただし、このフェーズの結果が状況を完全に反映するとは限らないことに注意してください。Terraform HCLからリソースを削除してterraform applyを実行すると、そのリソースはIaaS上で削除されます。HCLには存在しなくても、最後に正常にデプロイされた時点のTerraform stateにはまだ記録されているためです。TerraformはTF stateとIaaS APIを比較し、そのリソースを今後デプロイすべきでないと判断して削除します。そのため、環境内の依存関係や制約にも引き続き注意が必要です。AWSやAzureなどのクラウド環境では、通常、ポリシーガバナンスによって管理されます。
静的解析
リンターの利用も有効です。リンターを使うと、DevOpsチームはコードを解析し、エラー、バグ、疑わしいコードブロックを見つけられます。構文上の問題の特定に役立つだけでなく、セキュリティ上の問題の検出など、より重要な用途にも対応します。
Terraform向けのオープンソースのリンターツールはいくつかあり、それぞれ異なる解析方法でさまざまな対象プラットフォームに対応しています。GitHubには、複数のクラウドプロバイダーを対象にtflintを使うテンプレートが揃っています。
静的解析のユースケースの複雑さに応じて、単純な単体テストとして扱うことも、より複雑で高度なテストシナリオに組み込むこともできます。たとえば、テンプレートでパブリックIPアドレスが割り当てられた仮想マシンのデプロイが許可されている場合、リンターの検証でパブリックIPアドレスオブジェクトを検出し、エラーを出すことができます。また、コード内のハードコードされたパスワード文字列や接続文字列を検出することもできます。
統合テスト
個々の単体テストに合格しても、すべてのTerraform planを順番に実行するだけでは、全体の成功は保証されません。だからこそ統合テストが重要です。簡単に言えば、統合テストとは複数の単体テストを組み合わせて実行することです。Terraformでは、単体テストが通常ひとつのモジュールを対象とするのに対し、統合テストでは依存関係の多い複数のモジュールを検証します。
Terraformテンプレートが2つあるとします。ひとつは仮想ネットワークまたは仮想プライベートクラウド(VPC)を作成し、もうひとつは仮想マシンのインフラストラクチャをデプロイするものです。それぞれを個別の単体テストとして実行できますが、最終的には、デプロイ済みの仮想ネットワークコンポーネント上に仮想マシンを正常にデプロイする必要があります。いずれかのモジュールが異なるリージョンにデプロイされる場合、単体テストには合格しても、統合テストでは失敗します。
もうひとつ重要な違いがあります。単体テストは何もデプロイせずにオフラインで実行できますが、統合テストでは影響と成功を検証するためにリソースのデプロイが必要です。
統合テストに役立つツールのひとつがGruntworkのTerratestです。Go言語のフレームワークをベースに、テスト用のパッケージが組み込まれており、DevOpsチームはIaCのシナリオにも同じ原則を適用できます。
コンプライアンステスト
Terraformテンプレートを検証する際は、技術的なデプロイが企業のコンプライアンス規制に準拠している必要があります。そのため、地域ごとのコンプライアンス基準、命名規則、特定のVMタイプなどのインフラストラクチャ標準、ディスクストレージのセキュリティを確認するコンプライアンステストが必要です。
多くの場合、コンプライアンス検証は(または、そうあるべきですが)対象環境の構成の一部であり、AzureポリシーやAWSコンプライアンスセンターとの統合も含まれます。ただし、これらのポリシーは実際のデプロイ時にしか検証されないため、準拠していなければデプロイは失敗します。
TerraformのDevOpsプロセスにコンプライアンステストを組み込めば、デプロイ前にテストを実行し、デプロイの成功を確実にできます。ソリューションのひとつがTerraform-complianceです。Terraformテンプレートが組織のコンプライアンス要件を満たしているかを検証する外部ツールです。
エンドツーエンドテスト
最終的に、DevOpsチームはすべてのテスト方法をひとつのシナリオにまとめようとします。理想的には、すべてのテンプレートをテストし、すべてのモジュールをデプロイして、成功または失敗を検証します。
理想的に聞こえますが、エンドツーエンドテストには課題があります。テストに時間がかかるため、ボトルネックになることがあります。すばやく実行でき、すぐに結果が得られる単体テストと比べて、出力を受け取るまでにかなり時間がかかる場合があります。
CDKTFを使った単体テスト
ここまでの例では、テンプレートファイルにネイティブのHashiCorp Languageを使うことを前提としていました。しかしTerraformでは、CDKTF - Cloud Development Kit for Terraformを使った、より開発者向けのIaCアプローチも利用できます。
CDKTFを使うと、DevOpsチームはPython、C#、Go、Javaなど、従来の開発言語を使ってインフラストラクチャをデプロイできます。すべてのTerraformプロバイダーとモジュールがこのキットに対応しています。主なメリットは、チームがHCLを習得する必要がなく、既存の開発言語の知識を活用できることです。
CDKTFではテンプレートの作成方法やデプロイの実行方法が異なるため、単体テストの実行方法も変わります。CDKTFテストに関する最新のドキュメントはTerraformのウェブサイトで確認できます。
Snykのセキュリティツール
IaCのテストは、環境を健全に保つうえで不可欠です。さまざまなテスト手法を検討するだけでなく、テストにおけるセキュリティの側面にも目を向けることが重要です。Snykは次のような便利なツールを提供しています。
Snyk Infrastructure as Codeは、IaCの作成プロセスのあらゆる段階にセキュリティを組み込み、従来のアプリケーションソースコードと同様の方法でセキュリティコードスキャンを実行します。
前述のドリフトテストツールdriftctlはSnykが開発したもので、オープンソースのドリフト検出エンジンとして利用できます。
Snyk IaCには、業界ベンチマークに基づく豊富な事前定義済みセキュリティルール、クラウドプロバイダーのベストプラクティス、Snykの脅威モデリング調査が含まれています。また、Open Policy Agent(OPA)フレームワークとRegoクエリ言語を使って、Snyk IaCでカスタムルールを作成することもできます。
Terraformのセキュリティについて詳しく知る
テンプレートのテストは、テンプレート作成プロセスに欠かせません。テストには機能面でのメリットだけでなく、Terraformのデプロイにおけるセキュリティの最適化にも役立ちます。Terraformのデプロイテンプレートにセキュリティを組み込む方法について詳しく知りたい方は、Terraformを含むDevOpsや自動化パイプライン向けのセキュリティ検証ツールを提供するSnykをご覧ください。
ソースコードの段階からインフラを保護
Snykはワークフロー内のIaCセキュリティとコンプライアンスを自動化し、構成ドリフトや不足しているリソースを検出します。



