Terraform testのディレクトリ構成を考える

Terraform 1.6.0でテストフレームワークが実装されました。私の性格上、どのようなディレクトリ構成にすればよいのかということが気になりました。公式ではtestsディレクトリを作ってそこにテストファイルをまとめることができると書かれているので試してみました。

# 環境
Terraform 1.6.5

# ディレクトリ構成
私はいつもenvironmentsディレクトリ以下に環境毎ディレクトリを作成する構成にしています。コマンドを実行したルートディレクトリにあるtestsディレクトリは自動で読み込まれます。各環境毎testsディレクトリを作成する形にしました。
```
.
└── environments
    ├── dev
    │   ├── main.tf
    │   └── tests
    │       └── ...
    └── prod
        ├── main.tf
        ├── terraform.tfstate
        └── tests
            └── main.tftest.hcl
```
# ソース
```terraform:environments/prod/main.tf
resource "terraform_data" "this" {
    input = "try terraform test."
}
```
```terraform:environments/prod/tests/main.tftest.hcl
run "this_outputs_test" {
    assert {
        condition = terraform_data.this.output == "try terraform test."
        error_message = "outputが不正です。"
    }
}
```
# 実行
`init` `apply`を実行し、`test`を実行します。
__正常終了__
```bash
environments/prod$ terraform test
tests/main.tftest.hcl... in progress
  run "this_outputs_test"... pass
tests/main.tftest.hcl... tearing down
tests/main.tftest.hcl... pass

Success! 1 passed, 0 failed.
```
__異常終了__
テストファイルを変更してエラーを発生させます。
```diff_terraform:environments/prod/tests/main.tftest.hcl
-        condition = terraform_data.this.output == "try terraform test."
+        condition = terraform_data.this.output == "try terraform tests."
```
```bash
environments/prod$ terraform test
tests/main.tftest.hcl... in progress
  run "this_outputs_test"... fail
╷
│ Error: Test assertion failed
│
│   on tests/main.tftest.hcl line 5, in run "this_outputs_test":
│    5:         condition = terraform_data.this.output == "try terraform tests."
│     ├────────────────
│     │ terraform_data.this.output is "try terraform test."
│
│ outputが不正です。
╵
tests/main.tftest.hcl... tearing down
tests/main.tftest.hcl... fail

Failure! 0 passed, 1 failed.
```

# まとめ
各環境毎testsディレクトリを作成すればよさそうです。あとは共通モジュールのテストをどこに書くのかというのを考えます。

# その他
途中に知ったことですが、今回の主題と外れるので折りたたみにしました。
<details><summary>applayした後に作成される値はapplyした後でないとテストできない！</summary><div>

それはそうですけど、テストってそれを事前にやるものじゃないの？と思ったりしました。

```bash
$ terraform test
main.tftest.hcl... in progress
  run "this_outputs_test"... fail
╷
│ Error: Unknown condition value
│
│   on main.tftest.hcl line 5, in run "this_outputs_test":
│    5:         condition = terraform_data.this.output == "try terraform test."
│     ├────────────────
│     │ terraform_data.this.output is a string
│
│ Condition expression could not be evaluated at this time. This means you have executed a `run` block with `command =
│ plan` and one of the values your condition depended on is not known until after the plan has been applied. Either
│ remove this value from your condition, or execute an `apply` command from this `run` block.
╵
main.tftest.hcl... tearing down
main.tftest.hcl... fail

Failure! 0 passed, 1 failed.
```

> Condition expression could not be evaluated at this time. This means you have executed a `run` block with `command = plan` and one of the values your condition depended on is not known until after the plan has been applied. Either remove this value from your condition, or execute an `apply` command from this `run` block.

> 現時点では条件式を評価できませんでした。これは、command = plan を指定して run ブロックを実行し、プランが適用されるまで条件が依存する値の 1 つが不明であることを意味します。この値を条件から削除するか、この実行ブロックからapplyコマンドを実行してください。
</div></details>