TFLintに入門してみた
今回はTFLintに入門してみました。今まではTerraformを利用する際にLinterを導入していなかったので、TFLintを用いてLinter入門してみました。
TFLintとは?
TFLintはTerraformのプラグインであり、以下のような特徴を持つようです。
- 主要なクラウドプロバイダー(AWS/Azure/Google Cloud)の可能性のあるエラー(無効なインスタンスタイプなど)を検索
- 非推奨の構文や未使用の宣言について警告
- ベストプラクティス、命名規則を実施
私は主にGoogle Cloudに対して利用していましたが、主要なクラウドプロバイダーを対象としたチェックをしてくれると言うことで、とても有用そうです。
使ってみる!
インストール方法
インストール方法は以下に書かれています。私の環境はmacbookなので、以下のコマンドでインストールしました。
brew install tflint
tflintを適用してみる!
今回は過去の記事の以下に対して、作成していたコードに問題があるかをチェックさせてみました。
まずはここで作成したディレクトリ構成とコードを再掲しておきます。
main.tf
variables.tf
modules/
colab-template/
main.tf
variables.tf
vpc
main.tf
variables.tf
outputs.tf
main.tf
provider "google" {
project = var.project_id
region = var.region
}
module "vpc" {
source = "./modules/vpc"
project_id = var.project_id
region = var.region
}
module "colab-template" {
source = "./modules/colab-template"
project_id = var.project_id
region = var.region
network_id = module.vpc.network_id
subnetwork_id = module.vpc.subnetwork_id
}
variables.tf
variable "project_id" {
description = "The Google Cloud project ID"
type = string
}
variable "region" {
description = "The Google Cloud region"
type = string
default = "asia-northeast1"
}
modules/colab-template/main.tf
provider "google" {
project = var.project_id
region = var.region
}
resource "google_compute_network" "my_network" {
name = "colab-test-default"
auto_create_subnetworks = false
}
resource "google_compute_subnetwork" "my_subnetwork" {
name = "colab-test-default"
network = google_compute_network.my_network.id
region = var.region
ip_cidr_range = "10.0.1.0/24"
}
resource "google_colab_runtime_template" "runtime-template" {
name = "colab-runtime-template"
display_name = var.colab_enterprise_display_name
location = var.region
machine_spec {
machine_type = var.colab_enterprise_machine_type
}
data_persistent_disk_spec {
disk_type = var.data_persistent_disk_spec.disk_type
disk_size_gb = var.data_persistent_disk_spec.disk_size_gb
}
network_spec {
enable_internet_access = true
network = var.network_id
subnetwork = var.subnetwork_id
}
idle_shutdown_config {
idle_timeout = var.idle_timeout
}
euc_config {
euc_disabled = false
}
modules/colab-template/variables.tf
variable "project_id" {
description = "The Google Cloud project ID"
type = string
}
variable "region" {
description = "The Google Cloud region"
type = string
}
# Colab Enterprise variables
variable "colab_enterprise_display_name" {
description = "Colab Enterprise display name"
type = string
default = "sample-template"
}
variable "colab_enterprise_machine_type" {
description = "Colab Enterprise machine type"
type = string
default = "n2-standard-4"
}
variable "data_persistent_disk_spec" {
description = "Data persistent disk spec"
type = object({
disk_type = string
disk_size_gb = number
})
default = {
disk_type = "pd-standard"
disk_size_gb = 100
}
}
variable "network_id" {
description = "Network ID"
type = string
}
variable "subnetwork_id" {
description = "Subnetwork ID"
type = string
}
variable "idle_timeout" {
description = "Idle timeout"
type = string
default = "600s"
}
modules/vpc/main.tf
provider "google" {
project = var.project_id
region = var.region
}
resource "google_compute_network" "my_network" {
name = "colab-test-default"
auto_create_subnetworks = false
}
resource "google_compute_subnetwork" "my_subnetwork" {
name = "colab-test-default"
network = google_compute_network.my_network.id
region = var.region
ip_cidr_range = "10.0.1.0/24"
}
modules/vpc/variables.tf
variable "project_id" {
description = "The Google Cloud project ID"
type = string
}
variable "region" {
description = "The Google Cloud region"
type = string
}
variable "vpc_network" {
description = "VPC network"
type = object({
network = string
subnetwork = string
})
default = {
network = "default"
subnetwork = "default-asia-northeast1"
}
}
modules/vpc/outputs.tf
output "network_id" {
description = "The ID of the created VPC network."
value = google_compute_network.my_network.id
}
output "subnetwork_id" {
description = "The ID of the created VPC subnetwork."
value = google_compute_subnetwork.my_subnetwork.id
}
ルートディレクトリにてtflintを実行するとlintが実行されます。今回の結果は以下のようになっておりました。
tflint
# 結果
2 issue(s) found:
Warning: Missing version constraint for provider "google" in `required_providers` (terraform_required_providers)
on main.tf line 1:
1: provider "google" {
Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.13.0/docs/rules/terraform_required_providers.md
Warning: terraform "required_version" attribute is required (terraform_required_version)
on main.tf line 1:
Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.13.0/docs/rules/terraform_required_version.md
エラーはでず警告が発生して以下を指摘されました。
-
required_providersにてgoogleプロバイダーのバージョン指定がない - terraformの
required_versionの指定がない
lintが通るように修正
先ほど警告された内容に対応するためにmain.tfを以下のように修正してみました。
terraform {
required_version = ">= 1.0"
required_providers {
google = {
source = "hashicorp/google"
version = "~> 7.3"
}
}
}
provider "google" {
project = var.project_id
region = var.region
}
module "vpc" {
source = "./modules/vpc"
project_id = var.project_id
region = var.region
}
module "colab-template" {
source = "./modules/colab-template"
project_id = var.project_id
region = var.region
network_id = module.vpc.network_id
subnetwork_id = module.vpc.subnetwork_id
}
追加したのは以下の部分になります。そこでterraformのバージョン指定をしたのと、google providerのバージョンを指定しました。
terraform {
required_version = ">= 1.0"
required_providers {
google = {
source = "hashicorp/google"
version = "~> 7.3"
}
}
}
ここで改めてtflintを実行すると何も表示されず、lintの結果問題なしと判定されました。
ちなみに構文エラーとかがあると、、、
例えば先ほどのmain.tfのterraform部分を以下のように変更してみます。本来であればsourceとversionに値が入っているはずですが、ここではあえて空欄にしてみました。
terraform {
required_version = ">= 1.0"
required_providers {
google = {
source =
version =
}
}
}
この状態でtflintを実行すると以下のようにエラーが発生しました。みてわかるように、expressionが必要なのにないのでエラーがちゃんとでました。
tflint
# 結果
Failed to load configurations; main.tf:5,17-6,1: Invalid expression; Expected the start of an expression, but found an invalid expression token.:
Error: Invalid expression
on main.tf line 5, in terraform:
5: source =
6: version =
Expected the start of an expression, but found an invalid expression token.
まとめ
今回はTerraformようのLinterであるTFLintに入門してみました。今まではterraformコマンドを利用してエラーが出てなかったので使えてなかったですが、今後はちゃんとlinterを利用して安心安全なIaCの実現ができるように努めていこうと思います。
Discussion