1
0

TFLintのAWSルールセットを導入する

Posted at

はじめに

AWS環境構築で terraform を利用するにあたり、TFLint というのが環境チェックに有効そうだったので検証してみました。
今回は AWS のルールセットを導入して試してみました。

概要

・Terraformのコードをチェックすためのフレームワーク
・プラグインとして利用

導入方法

  • .tflint.hclファイルの作成
tflint
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
resource "aws_instance" "ec2" {
  ami           = var.ami
  instance_type = var.instance_type

  tags = {
    Name = "tflint-test"
  }
}

./modules/ec2/variables.tf

varilable
variable "ami" {
  type = string
}

variable "instance_type" {
  type = string
}

./ec2/main.tf

module
module "ec2" {
  source        = "../modules/ec2"
  ami           = "ami-0ca38c7440de1749a"
  instance_type = "t2.micro"
}

./ec2/versions.tf

terraform
terraform {
  required_version = ">= 1.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.50.0"
    }
  }
}

./ec2/.tflint.hcl

plugin
plugin "aws" {
    enabled = true
    deep_check = true
    version = "0.31.0"
    source  = "github.com/terraform-linters/tflint-ruleset-aws"
}

チェック

OK の場合

tflint
$ tflint

チェックが問題ない場合は何も出力されません。

NG の場合

例) 古いインスタンスタイプを指定した場合

現在は利用できないインスタンスタイプを指定した場合でも plan を実施するとエラーなどなく create 結果が表示されます。

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-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
$ 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 は問題なく通りました。

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
$ 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 はとても役にたつツールだなと感じました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0