Terratest を使って AWS 環境構築の検証を行う

# はじめに
Terratest というツールが色々と有名なので、これを利用してAWS環境の構築検証を行ってみました。

# 概要
Gruntwork.io が提供する terraform のテストツールです。
terraform で書かれたコード(tfファイル)をラッピングして `plan > apply > destroy` の一連処理を行います。対応言語は Go です。
- URL
  - 公式サイト - https://terratest.gruntwork.io/
  - GitHub - https://github.com/gruntwork-io/terratest

# ディレクトリ構成
```bash:tree
$ tree
.
├── ec2
│   └── main.tf
├── modules
│   └── alb
│       ├── main.tf
│       └── variables.tf
└── terratest
    └── alb_test.go
```

# ファイル
#### ./ec2/main.tf
EC2を作成するための terraform コードです。
今回の terraform はモジュール化してあるものを利用するため `source` で参照先のディレクトリを指定してます。
また、`ami` でイメージ `instance_type` でインスタンスタイプを指定しています。
`ami` はリージョンによって異なったり、頻繁に更新されるため注意です。
```tf:./ec2/main.tf
module "ec2" {
  source        = "../modules/ec2"
  ami           = "ami-0f75d1a8c9141bd00"
  instance_type = "t2.micro"
}
```

#### ./modules/ec2/main.tf
`./ec2/main.tf` の参照先になります。
ここでは単純に *terratest* という **Name** のインスタンスを作成するだけのコードになります。
```tf:./modules/ec2/main.tf
resource "aws_instance" "ec2" {
  ami           = var.ami
  instance_type = var.instance_type

  tags = {
    Name = "terratest"
  }
}
```

#### ./modules/ec2/variables.tf
変数の定義ファイルになります。
今回は `ami` と `instance_type` を変数として利用しているため定義しています。

```tf:./modules/ec2/variables.tf
variable "ami" {
  type = string
}

variable "instance_type" {
  type = string
}
```

#### ./terratest/ec2_test.go
terratestコードになります。ファイルの末尾は必ず `_test.go` にする必要があります。
また、`TerraformDir` に terraform のコードが配置されているディレクトリを相対パスで記述しています。
```go:./terratest/ec2_test.go
package test

import (
	"testing"

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

func TestTerraformAlbExample(t *testing.T) {
	// Construct the terraform options with default retryable errors to handle the most common
	// retryable errors in terraform testing.
	terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
		// Set the path to the Terraform code that will be tested.
		TerraformDir: "../ec2",
	})

	// Clean up resources with "terraform destroy" at the end of the test.
	defer terraform.Destroy(t, terraformOptions)

	// Run "terraform init" and "terraform apply". Fail the test if there are any errors.
	terraform.InitAndApply(t, terraformOptions)
}
```

## 実行コマンド
実際にコマンドを実行してみます。

```bash:cd
$ cd terratest
```
```bash:init
$ go mod init test
go: /Users/kohei/work/3shake/samples/terratest/go.mod already exists
```

```bash:tidy
$ go mod tidy
go: finding module for package github.com/gruntwork-io/terratest/modules/terraform
go: found github.com/gruntwork-io/terratest/modules/terraform in github.com/gruntwork-io/terratest v0.47.1
```

```bash:test
$ go test -v -timeout 30m
=== RUN   TestTerraformAlbExample
TestTerraformAlbExample 2024-09-25T13:26:30+09:00 retry.go:91: terraform [init -upgrade=false]
TestTerraformAlbExample 2024-09-25T13:26:30+09:00 logger.go:66: Running command terraform with args [init -upgrade=false]
TestTerraformAlbExample 2024-09-25T13:26:30+09:00 logger.go:66: Initializing the backend...
TestTerraformAlbExample 2024-09-25T13:26:30+09:00 logger.go:66: Initializing modules...
TestTerraformAlbExample 2024-09-25T13:26:30+09:00 logger.go:66: Initializing provider plugins...
TestTerraformAlbExample 2024-09-25T13:26:30+09:00 logger.go:66: - Reusing previous version of hashicorp/aws from the dependency lock file
TestTerraformAlbExample 2024-09-25T13:26:32+09:00 logger.go:66: - Using previously-installed hashicorp/aws v5.50.0
TestTerraformAlbExample 2024-09-25T13:26:32+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:32+09:00 logger.go:66: Terraform has been successfully initialized!
TestTerraformAlbExample 2024-09-25T13:26:32+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:32+09:00 logger.go:66: You may now begin working with Terraform. Try running "terraform plan" to see
TestTerraformAlbExample 2024-09-25T13:26:32+09:00 logger.go:66: any changes that are required for your infrastructure. All Terraform commands
TestTerraformAlbExample 2024-09-25T13:26:32+09:00 logger.go:66: should now work.
TestTerraformAlbExample 2024-09-25T13:26:32+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:32+09:00 logger.go:66: If you ever set or change modules or backend configuration for Terraform,
TestTerraformAlbExample 2024-09-25T13:26:32+09:00 logger.go:66: rerun this command to reinitialize your working directory. If you forget, other
TestTerraformAlbExample 2024-09-25T13:26:32+09:00 logger.go:66: commands will detect it and remind you to do so if necessary.
TestTerraformAlbExample 2024-09-25T13:26:32+09:00 retry.go:91: terraform [apply -input=false -auto-approve -lock=false]
TestTerraformAlbExample 2024-09-25T13:26:32+09:00 logger.go:66: Running command terraform with args [apply -input=false -auto-approve -lock=false]
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: Terraform used the selected providers to generate the following execution
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: plan. Resource actions are indicated with the following symbols:
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:   + create
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: Terraform will perform the following actions:
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:   # module.ec2.aws_instance.ec2 will be created
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:   + resource "aws_instance" "ec2" {
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + ami                                  = "ami-0f75d1a8c9141bd00"
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + arn                                  = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + associate_public_ip_address          = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + availability_zone                    = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + cpu_core_count                       = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + cpu_threads_per_core                 = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + disable_api_stop                     = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + disable_api_termination              = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + ebs_optimized                        = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + get_password_data                    = false
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + host_id                              = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + host_resource_group_arn              = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + iam_instance_profile                 = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + id                                   = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + instance_initiated_shutdown_behavior = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + instance_lifecycle                   = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + instance_state                       = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + instance_type                        = "t2.micro"
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + ipv6_address_count                   = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + ipv6_addresses                       = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + key_name                             = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + monitoring                           = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + outpost_arn                          = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + password_data                        = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + placement_group                      = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + placement_partition_number           = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + primary_network_interface_id         = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + private_dns                          = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + private_ip                           = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + public_dns                           = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + public_ip                            = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + secondary_private_ips                = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + security_groups                      = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + source_dest_check                    = true
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + spot_instance_request_id             = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + subnet_id                            = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + tags                                 = {
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:           + "Name" = "terratest"
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:         }
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + tags_all                             = {
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:           + "Name" = "terratest"
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:         }
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + tenancy                              = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + user_data                            = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + user_data_base64                     = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + user_data_replace_on_change          = false
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + vpc_security_group_ids               = (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + capacity_reservation_specification (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + cpu_options (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + ebs_block_device (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + enclave_options (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + ephemeral_block_device (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + instance_market_options (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + maintenance_options (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + metadata_options (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + network_interface (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + private_dns_name_options (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:       + root_block_device (known after apply)
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66:     }
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:33+09:00 logger.go:66: Plan: 1 to add, 0 to change, 0 to destroy.
TestTerraformAlbExample 2024-09-25T13:26:34+09:00 logger.go:66: module.ec2.aws_instance.ec2: Creating...
TestTerraformAlbExample 2024-09-25T13:26:44+09:00 logger.go:66: module.ec2.aws_instance.ec2: Still creating... [10s elapsed]
TestTerraformAlbExample 2024-09-25T13:26:47+09:00 logger.go:66: module.ec2.aws_instance.ec2: Creation complete after 13s [id=i-08755e261477460ae]
TestTerraformAlbExample 2024-09-25T13:26:47+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:47+09:00 logger.go:66: Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
TestTerraformAlbExample 2024-09-25T13:26:47+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:47+09:00 retry.go:91: terraform [destroy -auto-approve -input=false -lock=false]
TestTerraformAlbExample 2024-09-25T13:26:47+09:00 logger.go:66: Running command terraform with args [destroy -auto-approve -input=false -lock=false]
TestTerraformAlbExample 2024-09-25T13:26:48+09:00 logger.go:66: module.ec2.aws_instance.ec2: Refreshing state... [id=i-08755e261477460ae]
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66: Terraform used the selected providers to generate the following execution
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66: plan. Resource actions are indicated with the following symbols:
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:   - destroy
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66: Terraform will perform the following actions:
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:   # module.ec2.aws_instance.ec2 will be destroyed
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:   - resource "aws_instance" "ec2" {
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - ami                                  = "ami-0f75d1a8c9141bd00" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - arn                                  = "arn:aws:ec2:ap-northeast-1:637423332162:instance/i-08755e261477460ae" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - associate_public_ip_address          = true -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - availability_zone                    = "ap-northeast-1c" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - cpu_core_count                       = 1 -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - cpu_threads_per_core                 = 1 -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - disable_api_stop                     = false -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - disable_api_termination              = false -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - ebs_optimized                        = false -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - get_password_data                    = false -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - hibernation                          = false -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - id                                   = "i-08755e261477460ae" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - instance_initiated_shutdown_behavior = "stop" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - instance_state                       = "running" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - instance_type                        = "t2.micro" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - ipv6_address_count                   = 0 -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - ipv6_addresses                       = [] -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - monitoring                           = false -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - placement_partition_number           = 0 -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - primary_network_interface_id         = "eni-0b746d69ed4417d6b" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - private_dns                          = "ip-172-31-3-91.ap-northeast-1.compute.internal" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - private_ip                           = "172.31.3.91" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - public_dns                           = "ec2-43-206-153-107.ap-northeast-1.compute.amazonaws.com" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - public_ip                            = "43.206.153.107" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - secondary_private_ips                = [] -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - security_groups                      = [
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - "default",
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:         ] -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - source_dest_check                    = true -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - subnet_id                            = "subnet-007192f7fdc929639" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - tags                                 = {
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - "Name" = "terratest"
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:         } -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - tags_all                             = {
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - "Name" = "terratest"
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:         } -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - tenancy                              = "default" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - user_data_replace_on_change          = false -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - vpc_security_group_ids               = [
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - "sg-046d7a80c6bc84ee9",
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:         ] -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:         # (8 unchanged attributes hidden)
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - capacity_reservation_specification {
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - capacity_reservation_preference = "open" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:         }
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - cpu_options {
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - core_count       = 1 -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - threads_per_core = 1 -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:             # (1 unchanged attribute hidden)
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:         }
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - credit_specification {
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - cpu_credits = "standard" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:         }
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - enclave_options {
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - enabled = false -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:         }
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - maintenance_options {
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - auto_recovery = "default" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:         }
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - metadata_options {
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - http_endpoint               = "enabled" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - http_protocol_ipv6          = "disabled" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - http_put_response_hop_limit = 2 -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - http_tokens                 = "required" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - instance_metadata_tags      = "disabled" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:         }
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - private_dns_name_options {
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - enable_resource_name_dns_a_record    = false -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - enable_resource_name_dns_aaaa_record = false -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - hostname_type                        = "ip-name" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:         }
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:       - root_block_device {
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - delete_on_termination = true -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - device_name           = "/dev/xvda" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - encrypted             = false -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - iops                  = 3000 -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - tags                  = {} -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - tags_all              = {} -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - throughput            = 125 -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - volume_id             = "vol-055ea250d9ffe4720" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - volume_size           = 8 -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:           - volume_type           = "gp3" -> null
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:             # (1 unchanged attribute hidden)
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:         }
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66:     }
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66: Plan: 0 to add, 0 to change, 1 to destroy.
TestTerraformAlbExample 2024-09-25T13:26:49+09:00 logger.go:66: module.ec2.aws_instance.ec2: Destroying... [id=i-08755e261477460ae]
TestTerraformAlbExample 2024-09-25T13:26:59+09:00 logger.go:66: module.ec2.aws_instance.ec2: Still destroying... [id=i-08755e261477460ae, 10s elapsed]
TestTerraformAlbExample 2024-09-25T13:27:09+09:00 logger.go:66: module.ec2.aws_instance.ec2: Still destroying... [id=i-08755e261477460ae, 20s elapsed]
TestTerraformAlbExample 2024-09-25T13:27:19+09:00 logger.go:66: module.ec2.aws_instance.ec2: Still destroying... [id=i-08755e261477460ae, 30s elapsed]
TestTerraformAlbExample 2024-09-25T13:27:29+09:00 logger.go:66: module.ec2.aws_instance.ec2: Still destroying... [id=i-08755e261477460ae, 40s elapsed]
TestTerraformAlbExample 2024-09-25T13:27:39+09:00 logger.go:66: module.ec2.aws_instance.ec2: Still destroying... [id=i-08755e261477460ae, 50s elapsed]
TestTerraformAlbExample 2024-09-25T13:27:40+09:00 logger.go:66: module.ec2.aws_instance.ec2: Destruction complete after 50s
TestTerraformAlbExample 2024-09-25T13:27:40+09:00 logger.go:66: 
TestTerraformAlbExample 2024-09-25T13:27:40+09:00 logger.go:66: Destroy complete! Resources: 1 destroyed.
TestTerraformAlbExample 2024-09-25T13:27:40+09:00 logger.go:66: 
--- PASS: TestTerraformAlbExample (70.33s)
PASS
ok  	test	71.348s
```

# 画面遷移
terratest を実行した際の画面遷移です。
![スクリーンショット 2024-09-25 15.21.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/eaede2a3-e82e-8b0a-7853-9011e454d6d1.png)
![スクリーンショット 2024-09-25 15.21.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/3ff816c9-2efb-e4b1-797c-51757e214685.png)
![スクリーンショット 2024-09-25 15.21.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/c6f6cb82-7f1a-bc03-6460-fbe0e23d1a56.png)
![スクリーンショット 2024-09-25 15.21.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/569b099f-db8f-5add-1197-72c1ddc7af6a.png)
![スクリーンショット 2024-09-25 15.22.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/fa918d32-8577-348c-82ba-c9834864441e.png)
実際に作成し削除までされていることがわかります。


# 注意点
#### 差分チェックが行えない
**terratest** は **terraform** のコードを *apply* して *destroy* を行うまでが一連の流れとなります。
そのため、もし既存環境に導入した場合は *apply* した後に *destroy* が実施されてしまうため tf ファイルに記載されている全てのリソースの削除が行われてしまうため追加修正部分のみのチェックなどは難しいです。

#### ライセンス問題
Terraformのライセンス変更に伴って今後利用できなくなる可能性があります。

# まとめ
ということで以下まとると
- Gruntwork が提供するツール
- terraform の内容を実際に apply し deploy まで行う
- ファイル名は xxx_test.go
- Go 言語
- ライセンスの問題で利用できなくなるかも

という感じになります。

# おわりに
terraform の plan だと実際にリソース作成時にエラーが発生してしまうことがあります。
そのため terratest は実際にリソース作成まで行ってくれるためより正確な確認が行える点はとても良いです。
ただ、開発環境とかでも利用中のリソースに対して行うとリソース削除まで行ってしまうため注意が必要です。
また、実際にリソースの作成を行うため、少しの時間であってもAWS費用が発生する場合があります。
他にもライセンス問題などもあるため、あまり積極的に利用するのは控えた方が良いのかなというのが所感です。


# 参考
https://terratest.gruntwork.io/

https://github.com/gruntwork-io/terratest