📖

Unit testing for Terraform

2024/02/09に公開

Terraform v1.6.0からunit testの機能が追加されました。それを試してみます。
https://developer.hashicorp.com/terraform/language/tests

検証内容

  • TerraformでAWS EC2インスタンス構築する
  • その際にunit testでAMI IDをチェックする

前回のソースを使ってみたいと思います。
以下のような実装になっており、ami_idは ami-0506f0f56e3a057a4 を指定しています。
この設定があってるかを事前にテストしてみたいと思います。

environments/dev/main.tf
terraform {
  cloud {
    organization = "tsaeki"

    workspaces {
      name = "20240119_aws_dev"
    }
  }
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }

    required_version = ">= 1.2.0"
}


provider "aws" {
  region  = "ap-northeast-1"
}

module "ec2" {
  source        = "../../modules/ec2"
  ami_id        = "ami-0506f0f56e3a057a4"
  instance_type = "t2.micro"
  instance_name = "MyEC2Instance"
}

実装

moduleのoutputにAMI IDが出力するように設定

modules/ec2/output.tf
output "ami_id" {
  value = aws_instance.example.ami
}

ちなみにmoduleのmain.tfはこちらになります。変更点はありません。

modules/ec2/main.tf
resource "aws_instance" "example" {
  ami           = var.ami_id
  instance_type = var.instance_type
  tags = {
    Name = var.instance_name
  }
}

テストコードを作成

environments/dev/valid_ec2_ami.tftest.hcl
run "valid_ec2_ami_id" {
    command = plan

    assert {
        condition =  module.ec2.ami_id == "ami-0506f0f56e3a057a4"
        error_message = "Invalid AMI ID"
    }
}

実行

-> % terraform test
valid_ec2_ami.tftest.hcl... in progress
  run "valid_ec2_ami_id"... pass
valid_ec2_ami.tftest.hcl... tearing down
valid_ec2_ami.tftest.hcl... pass

Success! 1 passed, 0 failed.

テストが通りました。

次にわざと通らないようにしてみます。

environments/dev/valid_ec2_ami.tftest.hcl
run "valid_ec2_ami_id" {
    command = plan

    assert {
        condition =  module.ec2.ami_id == "ami-errortest" # 変更
        error_message = "Invalid AMI ID"
    }
}

テストを実行すると通らなくなります。

-> % terraform test
valid_ec2_ami.tftest.hcl... in progress
  run "valid_ec2_ami_id"... fail
╷
│ Error: Test assertion failed
│
│   on valid_ec2_ami.tftest.hcl line 5, in run "valid_ec2_ami_id":5:         condition =  module.ec2.ami_id == "ami-errortest"
│     ├────────────────
│     │ module.ec2.ami_id is "ami-0506f0f56e3a057a4"
│
│ Invalid AMI ID
╵
valid_ec2_ami.tftest.hcl... tearing down
valid_ec2_ami.tftest.hcl... fail

Failure! 0 passed, 1 failed.

メモ

  • command = planterraform plan で実行されるのかと思ったらされなかった。挙動要確認[1]

  • 最初 modules/ec2/output.tf ではなく environments/dev/output.tfを変更してて、なんでだろう、と時間を費やしました・・

-> % terraform test
valid_ec2_ami.tftest.hcl... in progress
  run "valid_ec2_ami_id"... fail
╷
│ Error: Unsupported attribute
│
│   on output.tf line 3, in output "ami_id":3:   value       = module.ec2.ami_id
│     ├────────────────
│     │ module.ec2 is a object
│
│ This object does not have an attribute named "ami_id".
╵
valid_ec2_ami.tftest.hcl... tearing down
valid_ec2_ami.tftest.hcl... fail

Failure! 0 passed, 1 failed.
  • tests というディレクトリでテストコードを書く
  • module側にテストコード入れる

参考

https://developer.hashicorp.com/terraform/language/tests
https://developer.hashicorp.com/terraform/tutorials/configuration-language/test
https://speakerdeck.com/torumakabe/an-toazuretoterraform-2024xin-chun-baziyon?slide=21

脚注
  1. planだけ実行するか、applyまでするか、の設定のようでした
    https://speakerdeck.com/torumakabe/an-toazuretoterraform-2024xin-chun-baziyon?slide=21 ↩︎

Discussion