🔖

自動テスト可能なインフラプロジェクトのための学習メモ 【令和6年3月改良最新版】

2024/01/29に公開

アプリ開発などに比べてテストがしづらいインフラ開発を、限界に近いレベルまでテストをしやすくするプロジェクトを現在設計中だが、まだ完成には程遠い状態である。

(追記)現在こちらのリポジトリで開発中。

だが、これまでに調べたツールやフレームワーク、テストプラクティスが結構な量になってきたので、ここでいったん設計の大枠レベルで有益だった情報を簡潔にまとめてみる。

CHANGELOG

CHANGELOG

2024/03/03追記

IaC Tool (Terraform)

現在自分が設計中のプロジェクトはTerraformでのインフラリソースの管理を前提としている。

ライセンス変更の問題などもあり、Pulumiも選択肢として十分あり得るような状況になり始めている気はしているが、やはり使い慣れている人数という点においては未だにTerraformの方が有利であることから、細かい問題には目をつぶってTerraformで行くことにする。

Terraform (公式ドキュメント)

https://developer.hashicorp.com/terraform

まず真っ先に紹介しなければいけないドキュメントはTerraformの公式ドキュメントである。

当たり前すぎて、なぜ紹介するのかと感じる人もいるとは思うが、Terraform関係無く初めて利用するツールやプログラム言語、ライブラリおよびフレームワーク、AWSやGCPのサービスなどはまず最初に公式ドキュメントを全部読むことで、その後の学習効率が段違いになる。

そもそも公式ドキュメントが提供する情報以上に正確かつ網羅度の高いドキュメントはほとんどのケースにおいて存在しないのだから、それ一つを読むだけでも十分過ぎる基礎学習となる。

(出来れば数ヶ月後の自分が有益な情報をすぐに思い出せるよう、メモを取りながら読むと尚良い)

新しい技術を公式ドキュメントで学習して、あとは実際に実装してみて問題が発生したらStack Overflowや技術サイト等で調べるだけで、実装だけでなく運用まで問題なく行えるようになると、個人的には確信に近いものを以って言える。

大抵のツールやフレームワーク、クラウドサービスの公式ドキュメントは、仮に全文英語であっても、そこそこ程度に英語のReadingが出来れば、1つにつき10時間前後ですべて読み終えられる。

もし英語が得意でなくても、昨今はDeepLなどで質の良い翻訳が可能なので、多少時間はかかるが翻訳ツールを使いながら読み進めることも出来るはず。

(自分も英文を読むのに疲れてくると、DeepLに適当に英文を放り込み始める)

この作業は工数にするとせいぜい1~2営業日程度であるのに対して、その後のシステム開発の品質レベルは段違いとなる。

そもそもシステムのアーキテクチャは、たった一文程度の情報を知っている/知らないの差だけで、天地の差が生まれるような世界であるため、そのような環境下にあってシステムローンチの最終局面で後悔をしないためにも、使用する技術の公式ドキュメントは全部読むことを繰り返し強くおすすめしたい。

以上、説教がましい話になったが、実際のところTerraformの公式ドキュメントは全ページ読もうとするとかなりの量があり、自分の見積りではおそらく最低でも30時間~程度はかかる気がしている。

よって、普段からTerraformを運用している、過去にTerraformを運用していた人は、追従できていない差分の機能に関するドキュメントだけを読んだ方がいい気もしている。

Terraform を使用するためのベスト プラクティス

https://cloud.google.com/docs/terraform/best-practices-for-terraform?hl=ja

Googleが推奨するTerraformを運用する上でのベストプラクティスがまとめられているページ。

自分は0.xバージョンの頃から実務的にインフラ作業から遠ざかっていたため、最近のTerraformの運用をどうするべきか調査していたところにこのページを見つけて、情報の体系化と設計の方針決めに大きく役立った。

ただ、実際に自動テスト可能なインフラプロジェクトを設計してみると、一部不都合が発生するものもあったりしたので、要件に応じて情報の取捨選択が必要にはなる。

Google Cloud の Terraform ブループリントとモジュール

https://cloud.google.com/docs/terraform/blueprints/terraform-blueprints?hl=ja

上記ベストプラクティスの中に"ブループリント"という気になる単語が出てくるが、これは特定の用途に必要なTerraformのモジュールやリソース群を1つに束ねたものをあらわすキーワードらしい。

GCPではモジュールとブループリントを以下のように定義している。

モジュールとは、Terraform リソースの論理的な要約を作成する、再利用可能な一連の Terraform 構成ファイルのことです。

ブループリントは、独自のソリューションを実装するためのモジュールとポリシーが文書化されたパッケージです。

GCPを利用している人であれば、環境を構築する際、まずはブループリントの方から探してみるといいのかもしれない。

あと再利用性を突き詰めれば、自作プロジェクトでもブループリントを作る可能性はゼロではないと思った。

(追記)実際にサンプルプロジェクトの実装でnetworkモジュールやsql-dbモジュールを使用していて十分に実用に耐えられそうだが、一方でthree-tier-web-appのような汎用性に問題があるものもあるため、利用の際には中身の調査が必須となる。

詳解 Terraform 第3版

https://www.oreilly.co.jp/books/9784814400522/

公式ドキュメントを読むことが一番良い基礎学習方法とは上に書いたが、やはり1つのテーマに対する体系化された知識を獲得するという点においては、本を読む方が効果的ではある。

Terraformは開発中のインフラプロジェクトの中心技術となるため、自分の場合は念の為に本でも学習することにした。

(個人的にO'reillyのファンであるため、まず欲しい技術本がO'reillyの日本語版にあればそれを読むようにしている)

ちなみに著者はTerratestの開発元であるGruntworkの関係者らしい。

内容としては、Terraformの基本構文を延々と紹介といったような一般的な入門本とは異なり、Terraformの実際の運用に役立つ知識を詰め込んだ一冊となっている。

特に9章 Terraformコードをテストするは、テスタブルなインフラを構築する上でかなり参考になった。

ただ自分の過去の記事でも書いたように、この本で紹介されているテストフレームワークTerratestはTeraformのライセンス変更の問題で、現在はTerraformとの併用が不可能に近い状態となっているので、この問題の回避策を追加で考える必要があった。

https://zenn.dev/erueru_tech/articles/c17bad1d0630f4

https://zenn.dev/erueru_tech/articles/203d76860c7af3

Test Framework

自動テスト可能なインフラプロジェクトを作るのだから、アプリケーションのソースコードに対してテストコードが出来るように、Terraformのコードに対してテストコードを実行できるようにする必要がある。

以下ではテストフレームワークやテストに役立つ記事を紹介。

Terraform Tests

https://developer.hashicorp.com/terraform/language/tests

自動テスト可能なインフラプロジェクトを作ろうとしたきっかけとなった機能。

インフラのコード(Terraformのresource等)もアプリケーションのテストコード同様にテスト可能な機能がついに誕生したとテンション高めで設計を始めたのだが、Terratestの誕生年などを考えると、やろうと思えばもっと昔から出来たのではと今では思う。

実装については、まだうまく体系化できていないため、出来次第記事を書きたいと考えている。

blueprint-test

https://pkg.go.dev/github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test

上記、Terraform を使用するためのベスト プラクティスでも紹介されている、Terraformのテスト用フレームワーク。

最終的にはterraform-execをインフラコードのテストフレームワークとして採用することにはなったが、テスタブルなTerraformプロジェクトのフォルダ構成を考えていた時期に出会って、その後の設計で影響を受けたページではあった。

ただblueprint-testフレームワーク自体については、テスト設計やフォルダ構成などへの制約が強めなのと、GCP寄りのフレームワークなのが、採用にあたってマイナスポイントにはなった。

またドキュメントはほとんどなく、実際に利用する場合にはソースコードを読む事になると考えた方がいい。

Terratest

https://terratest.gruntwork.io/docs/

Terraformのライセンス変更問題に気づくまでは、自動テスト可能なインフラプロジェクトを実現するためのファーストチョイスだったが、現在はterraform-execにその座を譲ってしまった。

一応Terratestをまだ諦めない人向けに多少言及すると、公式ドキュメントを読むのにそこまで時間かからないが、全部読んだところで正直使い方があまり分からないフレームワークとなっている。

利用にあたっては、Terratest自体のソースコードを参考にしながら、実装していくスタイルになる。

terraform-exec

https://github.com/hashicorp/terraform-exec

HashiCorpが自前で提供する、terraformコマンドをGo経由で実行するためのフレームワーク。

Terratestの機能の8割はterraformコマンドの実行であると前の記事でも書いたが、このterraform-execはその機能を持つため、テストに便利な機能面等でTerratestに比べて若干劣るが、代替足りうるというのが現在の評価。

そして、ここまで紹介したフレームワーク同様、ドキュメントがREADME.mdしか存在しないため、基本ソースコードやテストコードを見ながら実装することになる。

Testing HashiCorp Terraform

https://www.hashicorp.com/blog/testing-hashicorp-terraform

HashiCorpがインフラのテスト手法について言及している記事。

Terraform Tests & Mockを使用したテストをメインのテストフレームワークに据える場合はかなり参考になるはず。

その他

Terraformのコードのテストフレームワークには他にもKitchen-TerraformというRubyベースのものがある。

Linter

アプリのプロジェクトでは最低限パッケージ管理、リンタ、フォーマッタ、テストコードさえ入っていれば体を成す(と個人的には思ってる)ことから、インフラのコード開発でもリンタを入れたい。

そして、Terraformのリンタで最も有名なのがTFLintだった。

TFLint User Guide

https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/

上記フォルダ内のドキュメントは全部読むのにほとんど時間はかからないので、もちろん全部読むことをおすすめしたい。

またフォルダ内のドキュメントの他にもソースコードを調べると、ルールセット一覧のような重要な情報も見つかるので、少しコード探索してみるといい気がしている。

User Guide以外にも、自作のルールセットを開発する人向けのDeveloper Guideもあるが、こちらはTFLintをデフォルト設定で使うだけならそこまで読む必要は無かった。

Security Test

インフラプロジェクトではたった少しの設定ミスで不正アクセスや情報漏洩が発生する危険性があるため、自動でのセキュリティテストは確実に入れておきたい。

調査では以下の2つのツールが見つかった。

terrascan

https://runterrascan.io/docs

決して悪くないツールで導入してもよいが、保守コストが増える割にあまりメリットを教授できない気がするという印象を受けた。

具体的にはGCPを利用している場合、こちらで列挙されているチェックを行なってくれる。

firewallの設定を厚めにチェックしてくれているので、他のツールでセキュリティテストを行なっていて、その辺りが弱いなら併用の選択肢も出てくるのかもしれない。

ただ、実際に試してみて、再帰スキャンの挙動などで作り込みの甘さを感じるなど、不満に思うことが何度かあった。

何より以下で紹介するTrivyの方が明らかに高性能なので、自分の設計では導入見送りとなった。

Trivy

https://aquasecurity.github.io/trivy/latest/docs

最初はtfsecを調査しようとしたのだが、Trivyに買収、統合されたとのこと。

はっきり言ってドキュメントは理解しづらいものだったが、ツール自体は期待以上のものだった。

Trivyでは、Terraformのコードにセキュリティ上の問題がないかのスキャン(misconfig)以外にも、認証情報が含まれていないかのチェック(secret)、アプリケーションパッケージの脆弱性検査(vuln)、ライセンス違反探索(license)などを行なってくれる。

さらにAWSで環境を構築している場合、コマンド一つでダイレクトにセキュリティスキャンを行えるらしい(GCP向けは現在は存在しない)。

そして、デフォルトで提供されているセキュリティスキャン機能を使うだけなら導入コストはかなり低い。

一方でRego(下記)で実装したカスタムポリシーを用いたスキャンもサポートしているので拡張性も高い。

Compliance Test

このプロジェクトを開発していて、初めて知ったのがPolicy as Code(以後PaC)という単語。

ざっくり説明すると、あるプロダクトの状態がセキュリティルールや組織の方針に従っているかをテストする、といった領域で出てくるキーワードである。

具体的には、S3やGCSのバケットが外部公開される設定になっていないかをチェックしたり、データベースにprevent_destroy = trueの設定がされているか等をポリシーとして定義してチェックを行う。

そしてPaCを実現するためのランタイム/プログラム言語がOPA/Regoとなる。

(間違っている可能性もあるが、JavaでいうところのOPAがJREで、RegoがJavaみたいに認識している)

Terraformに対してOPAでポリシーチェックを行う場合、こちらのサンプルが参考になるが、やっていることは

入力値(terraform planコマンドなどを使用してJSON出力したプロダクトの状態)
↓
入力値がRegoで定義されたポリシーに合致した値となっているかテスト
↓
テスト結果(この値を元にCIのエラー終了など次の制御を決定)

のように抽象化出来る。

つまりJSONで状態を表現さえ出来れば、システム領域だけでなく、ありとあらゆる事象に対してooはxxでなければならないを定義できるはずである。

そしてポリシーはREST APIとして社内で一元管理して公開することも出来るため、すべてのプロジェクトに対してCIでこのポリシーサーバーでテストを行うことを義務付けることで、組織の方針を強制的に適用することが出来るようになる。

(融通の効かない人間の思考をAPI化出来るような所にロマンを感じる)

OPA/Rego入門

https://zenn.dev/mizutani/books/d2f1440cfbba94

基本的に新技術の調査は、ほとんどのケースにおいて英文の公式ドキュメントを読むところから始まるのだが、OPAに関してはこのZenn本のおかげで日本語で入門出来る。

やはり、ある程度の事前知識があった方が、英文のドキュメントをいきなり読むのに比べて、理解しやすい気がしている。

余談だが、O RLY Cover Generatorを使用した表紙のおかげで、本気でO'reillyの本のサンプルみたいなものだと思って読んでいた。

Open Policy Agent

https://www.openpolicyagent.org/docs/latest/

公式ドキュメント。

インフラプロジェクト設計当初はOPAネイティブな実行環境でポリシーテストの実装や実行を行おうと考えていたが、後述するConftestの方が簡単にポリシーテストを実現できそうというのが現在の感想。

Conftestで対応しきれなくなる場面では、やはり必要になりそうな気もしている。

Sentinel (Terraform Cloud)

https://developer.hashicorp.com/terraform/cloud-docs/policy-enforcement

Terraform Cloudを使用することで、利用可能となるポリシーテストの機能。

Terraform Cloud調査の記事でも書いたが、実質有料の機能であるにも関わらず、HashiCorp製品限定のプログラム言語であるSentinelを覚えなければいけないため、より幅広く利用されているOPAを使ってポリシーテストを行った方がよいというのが個人的な感想。

そして何より次に紹介するConftestがポリシーテストのツールとして、自分の環境では一番優れているので必要とはならなかった。

Conftest

https://www.conftest.dev/

Conftestの紹介記事で実践的な利用方法を詳しく書いたが、TerraformのHCLファイルに限らず、Kubernetes、Dockerfile、その他各種設定ファイルのポリシーテストを簡単に行うことが出来る、かなりおすすめのツール。

そもそもこのツールはOPA自身から提供されているものなので、ポリシーはもちろんOPAで実装することになる。

自分のインフラプロジェクトではConftestをポリシーテスト役として採用した。

Drift Detection

driftctl

https://github.com/snyk/driftctl

Terraformのstateで管理されていないリソースを検出するためのツール。

Terraform関連ツールとしては珍しくAWSだけでなくGCPにも対応していて、本来であればファーストチョイスとなるツールだった。

しかし残念ながら現在メンテナンスモードとなっていて、将来的に問題が発生した場合への対応に懸念が残るため、採用を断念した。

Drift Detection (Terraform Cloud)

https://developer.hashicorp.com/terraform/cloud-docs/workspaces/health

Terraform Cloudではポリシーテストだけでなく、ドリフト検知の機能も提供している。

こちらもTerraform Cloudの調査で機能を調べたが、機能は劣るものの数行のコマンドで似たようなドリフト検知機能を自前で実装できそうなので不採用となった。

Miscellaneous Tools

tfenv

https://github.com/tfutils/tfenv

ローカルのTerraformのバージョンを簡単に切り替えられるようにするツール。

導入手順はこちらの記事でまとめている。

pre-commit

https://pre-commit.com/

Githubにコード変更をpushする前に、上記TFLintやTrivyによるチェックを自動的に行うようにするためのツール。

pre-commitについての詳細はこちらの記事でまとめている。

おわり

引き続き情報が集まり次第、情報の加筆・修正を随時行なっていきたい。

Discussion