Version固定でTFLintをインストールする

2021.07.31

TFLintとは

その名の通りTerraformのlinterツールです。非推奨構文の使用、未使用の変数の宣言、ベストプラクティスに沿っていない記述、また存在しないEC2インスタンスタイプの使用などをチェックして報告してくれます。

TFLintのVersionが重要

TFlintの実行環境には、別途のTerraformのインストールは不要です。TFLintにTerraformが内蔵されているからです。

しかしそれ故に、TFLint内で使われるTerraformのVersionは、TFLintのVersionに依存するということになります。LintをかけるTerraformのコードのVersionと、TFLint内のTerraformのVersionが一致するようにすることが重要です。一致していない場合、チェック結果が間違う可能性があります。

TFLintの各VersionがどのTerraformのVersionを使用しているかは、以下のページのGitのタグを切り替えて確認してください。

状況

私は現在参画中のプロジェクトにて、CI環境でTFLintを実行しています。使用しているTerraformのVersionは0.14.5だったので、対応しているTFLintのVersionは0.24.1です。

CIのジョブ内でインストールスクリプトを実行してインストールし、その後tflintコマンドを実行していました。

Version指定(失敗)

前述のとおりTFLintのVersionを0.24.1に固定する必要があります。この方法として、0.24.1のタグが打たれている前述のインストールスクリプトを実行すれば良いと考えました。具体的には以下です。

$ curl https://raw.githubusercontent.com/terraform-linters/tflint/v0.24.1/install_linux.sh | sh

ですがこの方法は間違いでした。たとえ0.24.1のタグが打たれているスクリプトを使ったとしても、最新版がインストールされます。結果、対応しているTerraformのVersionが1.0.0になり、以下のようなエラーが検出されるようになりました。

Experiment "provider_sensitive_attrs" is no longer available. Provider-defined sensitive attributes are now redacted by default, without enabling an experiment.

このエラーの意味ですが、provider_sensitive_attrsはもうexperiment featureじゃなくなったので、明示的に使用を宣言しなくてもデフォルトで使えるよというものです。 確かに1.0.0時点ではこの機能はデフォルトになっていますが、使用しているVersion0.14.5時点ではexperiment featureなのです。こうのような感じでTFLintのVersionがズレるとチェック結果が間違う場合があります。

Version指定(成功)

インストールスクリプトの中身を確認したところ、環境変数でVersionを指定するのが正しいやり方でした。

if [ -z "${TFLINT_VERSION}" ] || [ "${TFLINT_VERSION}" == "latest" ]; then
  echo "Looking up the latest version ..."
  version=$(get_latest_release)
else
  version=${TFLINT_VERSION}
fi

GitLab Runnerでの実装

今回のCI環境はGitLab Runnerでした。GitLab Runnerでの環境変数の指定方法は以下のようになります。

lint:
  stage: static-test
  variables:
    TFLINT_VERSION: v0.24.1
  script:
    - terraform init -backend=false
    - apk add -q curl unzip sudo
    - curl https://raw.githubusercontent.com/terraform-linters/tflint/v0.24.1/install_linux.sh | sh
    - tflint --config=.tflint.hcl

Docker Imageを使おう

そもそもの話ですが、単にTFLintを使いたいだけなのであれば、ジョブ内でインストールせず既存のTFLintのDocker Imageを利用することを第一に考えたほうが、ジョブの実行時間が短縮されるので良いと思います。