はじめに
terraform validate
やterraform plan
では検知できないエラーを見つけるために、TFLintを利用してみました。TFLintを用いれば、例えばインスタンスタイプの誤りや命名規約違反を検知できます。
本記事では、インストールから利用方法までを記載しています。
TFLintとは?
いわゆるTerraformのためのLinter。JavaScriptでいうと、ESLintのようなものです。構文やパラメータがルールに違反していないかをチェックしてくれるツールです。
環境やバージョン
今回利用した環境です。
tflintをインストール
- tflint/releasesから
tflint_windows_amd64.zip
をダウンロード
tflint_windows_amd64.zip
を解凍
tflint.exe
をパスが通ってるところに配置
- 以下を実行し、バージョン情報が出たら成功
PowerShell1 2 3
| $ tflint --version
TFLint version 0.34.0
|
※他OSでのインストール手順は以下を参照ください。
.tflint.hclの作成
.tflint.hcl
とは、Pluginをインストールするための設定ファイルです。
今回は、GCPの RuleSet Pluginをインストールする例を記載します。
.tflint.hcl
はホームディレクトリか、カレントディレクトリに配置する必要がある
.tflint.hcl1 2 3 4 5
| plugin "google" { enabled = true version = "0.15.0" source = "github.com/terraform-linters/tflint-ruleset-google" }
|
※参考
tflint –initの実施
.tflint.hcl
を記載したあとに、Pluginをインストールするために、以下のコマンドを実行します。初回のみ実施で問題ないです。
PowerShell
tflintの動作確認をしてみる
google_compute_instance
のmachine_type
に存在しないインスタンスタイプを記載してみます。
example.tf1 2 3 4 5 6 7 8
| resource "google_compute_instance" "gce_test" { project = "testest" name = "testtest-gce001" zone = "asia-northeast1-a" # ここで存在しないインスタンスタイプを指定 machine_type = "n2-standard-200" ... }
|
- tflintを実行してみる。そうするとエラーがでます
PowerShell1 2 3 4 5 6 7 8
| $ tflint
1 issue(s) found:
Error: "n2-standard-200" is an invalid as machine type (google_compute_instance_invalid_machine_type)
on main.tf line 6: 6: machine_type = "n2-standard-200"
|
応用:moduleも対象とする
Terraformにはmoduleと呼ばれるカスタムリソースを作る機能があります。詳しくはTerraformerとしてコードを書いて思うことを参照ください。
これをTFLintでチェックするためには、Module Inspectionに記載がある通り、.tflint.hcl
にmodule = true
を追記するだけです。
.tflint.hcl1 2 3 4 5 6 7 8 9 10
| config { module = true }
plugin "google" { enabled = true version = "0.15.0" source = "github.com/terraform-linters/tflint-ruleset-google" }
|
応用:ルールを有効化する
TFLintに多くのチェックルールが予め用意されています。どんなルールがあって、どれがデフォルトで有効になっているかは以下に記載があるので確認すると良いでしょう。
今回は例として、「terraform_unused_declarations」を有効化してみます。内容としては、「使っていないlocalsを検知できる」というルールです。
チェックするために、 先程の .tflint.hcl
に terraform_unused_declarations
を追記します。
.tflint.hcl1 2 3 4 5 6 7 8 9 10 11 12 13 14
| config { module = true }
plugin "google" { enabled = true version = "0.15.0" source = "github.com/terraform-linters/tflint-ruleset-google" }
rule terraform_unused_declarations { enabled = true }
|
使っていないlocalsを宣言したtfファイルを追加します。
example-valiable.tf1 2 3
| locals { unused = "test" }
|
これに対して、TFLint実行します。ルール違反を検知したことがわかります。どのファイルの何行目に違反があったか表示してくれていますね。
PowerShell1 2 3 4 5 6 7 8 9 10
| $ tflint
1 issue(s) found:
Warning: local.unused is declared but not used (terraform_unused_declarations)
on example-valiable.tf line 2: 168: unused = "test"
Reference: https://github.com/terraform-linters/tflint/blob/v0.34.0/docs/rules/terraform_unused_declarations.md
|
利用上の注意点
TFLintを使っていくなかで、注意しなければと思ったものをあげていきます。
1. Local Valuesは評価されない
TFLint skips expressions that reference static local values #571にも記載があります。以下のように不正なインスタンスタイプをlocalsで定義してもエラーにならないです。
example.tf1 2 3 4 5 6 7 8 9 10 11
| locals { machine_type = "n2-standard-200" }
resource "google_compute_instance" "gce_test" { project = "testest" name = "testtest-gce001" zone = "asia-northeast1-a" machine_type = local.machine_type ... }
|
tflintの実行
Compatibility with Terraformのドキュメントに記載がある通り、TFLintはTerraformを内蔵しています。そのため、利用しているTerraformのバージョンに合わせて、該当バージョンのTFLintを利用する必要がある
直近のバージョン対応表をあげます。
※参考
3. Deep Checkingを利用する場合の注意事項
Deep Checkingは、GCPのAPIを利用してより厳密なチェックを行うことができるオプションです。
以下のようにdeep_check = true
を追加することで、Deep Checkingが有効になります。ただし、serviceusage.googleapis.com
が有効になっている必要があります。つまり、PJ作成時(APIが有効になっていない状態)にtflintを実行するとエラーになってしまうのでご注意ください。
.tflint.hcl1 2 3 4 5 6 7
| plugin "google" { enabled = true version = "0.15.0" source = "github.com/terraform-linters/tflint-ruleset-google" deep_check = true }
|
※Projectは、providerのprojectを参照している
example.tf1 2 3
| provider "google" { project = "testtest" }
|
.tflint.hcl のサンプルを用意したので、TFLintを動かしてみよう
全ルールをenableにした.tflint.hcl
をサンプルとして用意しました。全ルールとは以下に記載のあるルールです。
.tflint.hcl1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
| config { module = true }
plugin "google" { enabled = true version = "0.15.0" source = "github.com/terraform-linters/tflint-ruleset-google" deep_check = false }
rule "terraform_comment_syntax" { enabled = true }
rule "terraform_deprecated_index" { enabled = true }
rule "terraform_deprecated_interpolation" { enabled = true }
rule "terraform_documented_outputs" { enabled = true }
rule "terraform_documented_variables" { enabled = true }
rule "terraform_module_pinned_source" { enabled = true }
rule "terraform_module_version" { enabled = true }
rule "terraform_naming_convention" { enabled = true }
rule "terraform_required_providers" { enabled = true }
rule "terraform_required_version" { enabled = true }
rule "terraform_standard_module_structure" { enabled = true }
rule "terraform_typed_variables" { enabled = true }
rule "terraform_unused_declarations" { enabled = true }
rule "terraform_unused_required_providers" { enabled = true }
rule "terraform_workspace_remote" { enabled = true }
rule "google_composer_environment_invalid_machine_type" { enabled = true }
rule "google_compute_instance_invalid_machine_type" { enabled = true }
rule "google_compute_instance_template_invalid_machine_type" { enabled = true }
rule "google_compute_reservation_invalid_machine_type" { enabled = true }
rule "google_container_cluster_invalid_machine_type" { enabled = true }
rule "google_container_node_pool_invalid_machine_type" { enabled = true }
rule "google_dataflow_job_invalid_machine_type" { enabled = true }
rule "google_project_iam_audit_config_invalid_member" { enabled = true }
rule "google_project_iam_binding_invalid_member" { enabled = true }
rule "google_project_iam_member_invalid_member" { enabled = true }
rule "google_project_iam_policy_invalid_member" { enabled = true }
|
実運用上は利用しないルールを、個別にdisableにし、検知結果に対して運用が回るように調整していくことが重要かなと思います。
まとめ
TFLintを使うことで、terraform validate
やterraform plan
で検知できないエラーを見つけることができました。
RuleSetに限りがあるので全エラーを検知できるとまでいきませんが、TFLintを導入することでterraform apply
で失敗するケースが減っていくと考えています。