🗂
Terraform Checks
俺とAzureとTerraform ~2024新春バージョン~を読んでて、Checks
という機能もあることを知ったので試してみようと思います。
検証内容
起動したEC2インスタンスのインスタンスタイプのチェックとインスタンス名のチェックをしてみます。
また前回のソースを使っていきます。
実装
構成はこんな感じです。environments
配下にメインのソース、modules
配下にmoduleがあります。ec2_instanceを作成するmoduleになっています。
※valid_ec2.tftest.hclは前回のがそのままあるだけです
-> % tree
.
├── README.md
├── environments
│ └── dev
│ ├── main.tf
│ ├── output.tf
│ └── tests
│ └── valid_ec2.tftest.hcl
├── modules
│ └── ec2
│ ├── README.md
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
└── terraform.tf
5 directories, 9 files
moduleのoutput追加
instance_type
とinstance_name
をoutputするように追加します。
modules/ec2/outout.tf
output "instance_type" {
value = aws_instance.example.instance_type
}
output "instance_name" {
value = aws_instance.example.tags.Name
}
check block追加
check "instance_type"
とcheck "name_tag"
を追加します。
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"
}
### こちらを追加しました
check "instance_type" {
assert {
condition = module.ec2.instance_type == "t2.micro"
error_message = "The instance type is not t2.micro"
}
}
check "name_tag" {
assert {
condition = module.ec2.instance_name == "MyEC2Instance"
error_message = "The instance name is not MyEC2Instance"
}
}
planを実行
terraform plan
を実行してみます。問題なく実行されます。
-> % terraform plan
Running plan in Terraform Cloud. Output will stream here. Pressing Ctrl-C
will stop streaming the logs, but will not stop the plan running remotely.
Preparing the remote plan...
The remote workspace is configured to work with configuration at
/environments/dev relative to the target repository.
Terraform will upload the contents of the following directory,
excluding files or directories as defined by a .terraformignore file
at /home/tsaeki/Develop/20240119_aws/.terraformignore (if it is present),
in order to capture the filesystem context the remote workspace expects:
/home/tsaeki/Develop/20240119_aws
To view this run in a browser, visit:
https://app.terraform.io/app/tsaeki/20240119_aws_dev/runs/run-Rz1pCKz24bXXtX2S
Waiting for the plan to start...
Terraform v1.7.0
on linux_amd64
Initializing plugins and modules...
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# module.ec2.aws_instance.example will be created
+ resource "aws_instance" "example" {
+ ami = "ami-0506f0f56e3a057a4"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ disable_api_stop = (known after apply)
+ disable_api_termination = (known after apply)
+ ebs_optimized = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ host_resource_group_arn = (known after apply)
+ iam_instance_profile = (known after apply)
+ id = (known after apply)
+ instance_initiated_shutdown_behavior = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t2.micro"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = (known after apply)
+ monitoring = (known after apply)
+ outpost_arn = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ placement_partition_number = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ secondary_private_ips = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ subnet_id = (known after apply)
+ tags = {
+ "Name" = "MyEC2Instance"
}
+ tags_all = {
+ "Name" = "MyEC2Instance"
}
+ tenancy = (known after apply)
+ user_data = (known after apply)
+ user_data_base64 = (known after apply)
+ user_data_replace_on_change = false
+ vpc_security_group_ids = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ id = (known after apply)
意図的に間違えてみる
checkの条件を変えて意図的に間違えてみます。
environments/dev/main.tf
### こちらを追加しました
check "instance_type" {
assert {
condition = module.ec2.instance_type == "t3.micro" # t3.microに変更
error_message = "The instance type is not t2.micro"
}
}
check "name_tag" {
assert {
condition = module.ec2.instance_name == "MyEC2InstanceTest" # MyEC2InstanceTestに変更
error_message = "The instance name is not MyEC2Instance"
}
}
すると以下のようにWarningが出るようになります。
Waiting for the plan to start...
Terraform v1.7.0
on linux_amd64
Initializing plugins and modules...
╷
│ Warning: Check block assertion failed
│
│ on main.tf line 40, in check "name_tag":
│ 40: condition = module.ec2.instance_name == "MyEC2InstanceTest"
│ ├────────────────
│ │ module.ec2.instance_name is "MyEC2Instance"
│
│ The instance name is not MyEC2Instance
╵
╷
│ Warning: Check block assertion failed
│
│ on main.tf line 33, in check "instance_type":
│ 33: condition = module.ec2.instance_type == "t3.micro"
│ ├────────────────
│ │ module.ec2.instance_type is "t2.micro"
│
│ The instance type is not t2.micro
╵
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# module.ec2.aws_instance.example will be created
+ resource "aws_instance" "example" {
+ ami = "ami-0506f0f56e3a057a4"
こんな感じで事前にリソースのチェックができます。
TestsとChecksの使い分け
俺とAzureとTerraform ~2024新春バージョン~とかTerraformのChecksとTestsの使い分けを参考にするとよさそうです。
ざっくりこんな感じでしょうか。ただ実際に運用してみないとですね・・
Tests
- modulesのunitテスト
- integrationテスト
Checks
- 起動後の動作確認(e2eテスト)
Discussion