はじめに
AWS環境構築で terraform を利用するにあたり、TFLint というのが環境チェックに有効そうだったので検証してみました。
今回は AWS のルールセットを導入して試してみました。
概要
・Terraformのコードをチェックすためのフレームワーク
・プラグインとして利用
導入方法
- .tflint.hclファイルの作成
plugin "aws" {
enabled = true
deep_check = true
version = "0.31.0"
source = "github.com/terraform-linters/tflint-ruleset-aws"
}
- tflint --init の実施
検証
ディレクトリ構成
$ tree
.
├── modules
│ └── ec2
│ ├── main.tf
│ └── variables.tf
└── ec2
├── main.tf
└── versions.tf
tfファイル
./modules/ec2/main.tf
resource "aws_instance" "ec2" {
ami = var.ami
instance_type = var.instance_type
tags = {
Name = "tflint-test"
}
}
./modules/ec2/variables.tf
variable "ami" {
type = string
}
variable "instance_type" {
type = string
}
./ec2/main.tf
module "ec2" {
source = "../modules/ec2"
ami = "ami-0ca38c7440de1749a"
instance_type = "t2.micro"
}
./ec2/versions.tf
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.50.0"
}
}
}
./ec2/.tflint.hcl
plugin "aws" {
enabled = true
deep_check = true
version = "0.31.0"
source = "github.com/terraform-linters/tflint-ruleset-aws"
}
チェック
OK の場合
$ tflint
チェックが問題ない場合は何も出力されません。
NG の場合
例) 古いインスタンスタイプを指定した場合
現在は利用できないインスタンスタイプを指定した場合でも plan を実施するとエラーなどなく create 結果が表示されます。
$ terraform plan
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.ec2 will be created
+ resource "aws_instance" "ec2" {
+ ami = "ami-0ca38c7440de1749a"
+ 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_lifecycle = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t1.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
+ spot_instance_request_id = (known after apply)
+ subnet_id = (known after apply)
+ tags = {
+ "Name" = "tflint-test"
}
+ tags_all = {
+ "Name" = "tflint-test"
}
+ 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.
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
tflint を実施します。
$ tflint
1 issue(s) found:
Warning: "t1.micro" is previous generation instance type. (aws_instance_previous_type)
on main.tf line 4:
4: instance_type = "t1.micro"
Callers:
main.tf:4,19-29
../modules/ec2/main.tf:3,19-36
Reference: https://github.com/terraform-linters/tflint-ruleset-aws/blob/v0.31.0/docs/rules/aws_instance_previous_type.md
Warning
として「t1.micro は前世代のインスタンスタイプです」と指摘されました。
また、 main.tf の 4行目ですと場所も表示されます。
例) 存在しないamiを指定した場合
ここでは通常のインスタスIDに一文字足して明らかに桁が多い ami を指定してみたところ plan は問題なく通りました。
$ terraform plan
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.ec2 will be created
+ resource "aws_instance" "ec2" {
+ ami = "ami-0ca38c7440de1749aa"
+ 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_lifecycle = (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
+ spot_instance_request_id = (known after apply)
+ subnet_id = (known after apply)
+ tags = {
+ "Name" = "tflint-test"
}
+ tags_all = {
+ "Name" = "tflint-test"
}
+ 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.
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
tflint実施します。
$ tflint
1 issue(s) found:
Error: "ami-0ca38c7440de1749aa" is invalid AMI ID. (aws_instance_invalid_ami)
on main.tf line 3:
3: ami = "ami-0ca38c7440de1749aa"
Callers:
main.tf:3,19-43
../modules/ec2/main.tf:2,19-26
今度は Error
が表示され「AMI ID が不正です」と指摘してくれました。
懸念点
Terraformのライセンス変更による影響は受けないか?
TFLint は HashiCorp が提供するツールではないためライセンス違反などが気になりますが以下のサイトに調べてくださっている方がいました。
HashiCorp からも大丈夫と回答が来てるので将来的にも利用できなくなる確率は低いと思われます。
おわりに
AWS を構築する上で利用できない値などがあった場合は apply 前に知りたかったので TFLint はとても役にたつツールだなと感じました。