こんにちは、今年の10月に入社したプラットフォーム開発グループ DPEチームの酒井です。
先日 GitHub Actions に TFLint と Trivy を導入しました。
まとめて書くと長くなってしまうので、今回は TFLint 導入編です。
今回説明する部分は以下になります。
TFLint の設定
TFLint を GitHub Actions で動かす
TFLintとは?
TFLint は、Terraform ファイルの命名規則や、インスタンスタイプのエラー、非推奨の構文、未使用の宣言など、静的解析してくれるフレームワークです。 github.com
TFLint 導入
TFLint の install
ビザスクの Terraform 環境周りではCLIパッケージマネージャーとして aqua を利用しています。
TFLint は aqua registry に存在していますので、aqua.yaml に以下のように追記していきます。
registries: - type: standard ref: v4.97.0 packages: - name: terraform-linters/tflint@v0.49.0
※ 現状だと、Terraform v1.xに対応しているとのことなので最新を取得すれば良さそうです。
https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/compatibility.md
使用できるプラグイン
AWS/Azure/GCP に関しては、ルールセットのプラグインとして既に公式で用意されているようです。
ビザスクでは主に GCP を利用していますので、こちらを使ってルールを記述していきます。
- GCPのrule set: github.com
基本的な TFLint の使い方
プラグインの導入
.tflint.hcl
ファイルを作成する- 使用するプラグインの記載
- 以下を実行すると、`.tflint.hcl`ファイルに記載したプラグインがインストールされる
- インストールしたプラグインは以下のコマンドで確認可能
- lint の実行
- 問題の修正 fixオプションを指定することで、一部は自動的に修正してくれます。
plugin "google" { enabled = true version = "0.25.0" source = "github.com/terraform-linters/tflint-ruleset-google" }
$ tflint --init
$ tflint -v TFLint version 0.48.0 + ruleset.google (0.25.0) + ruleset.terraform (0.4.0-bundled)
$ tflint
$ tflint --fix
moduleの中まで再帰的にチェックする
以下を.tflint.hcl
記述することで、module 内まで lint の対象にしてくれます。
config { module = true }
再帰の場合には以下のコマンドで実行ができます。
下の階層をチェックする際に.tflint.hcl
のファイルのパスがずれてしまうようなので、絶対パスで指定してあげる必要があります。
$ tflint --recursive -c $(realpath .tflint.hcl)
fix オプションを指定することで、再帰的に自動修正してくれます。
$ tflint --recursive -c $(realpath .tflint.hcl) --fix
また、以下のようにignore-module
オプションを指定することで特定のモジュールのみチェックを回避することもできます。
$ tflint --ignore-module=./module
その他使いそうなコマンドオプション
--format
出力形式の変更(json形式にできたりする)--var-file
Terraform 変数を設定するterraform.tfvars
ファイルが存在する場合には自動的にロードされる
最終的なルールセット
config { module = true } plugin "google" { enabled = true version = "0.25.0" source = "github.com/terraform-linters/tflint-ruleset-google" } plugin "terraform" { enabled = true } rule terraform_documented_outputs { enabled = false } rule terraform_documented_variables { enabled = false } rule terraform_naming_convention { enabled = false } rule terraform_required_version { enabled = false } rule terraform_required_providers { enabled = false }
ルールを一通り有効にした後に、不要なものを無効にする形で記述しています。
どのルールを有効にして、どのルールを無効にするのかということは正直好みだと思います。
Terraform のルールセットは default が recommend
のものだけ有効になりますので、運用していくなかで不要なものがあれば無効にする程度で良いと思います。
Terraform のルールセット:
TFLintをGitHubActionsで動かす
詰まった事
TFLint は動かすためにterraform init
する必要があります。
どうやって GitHub Action 上でterraform init
するかで少し行き詰まりました。
state ファイルは GCP の Cloud Strage に置いていたので、取れる手段は2つあります。
override.tf
を作成し、local 上に state ファイルを作成する。
- GCPの一時的な credential を発行する。
今回は init するだけで、現状のリソースがどうなっているかということは関係ないので、より簡単にできる override.tf
を作成する方法を選択しました。
最終的な設定ファイル
GitHub Actionsの設定は以下になります。
tflint: name: Run tflint runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.ref }} - name: Detect Terraform version run: | printf "TF_VERSION=%s" $(cat aqua.yaml | grep "hashicorp/terraform" | awk -F '@v' '{print $2}') >> $GITHUB_ENV - name: Install terraform uses: hashicorp/setup-terraform@v3 with: terraform_version: ${{ env.TF_VERSION }} - name: dev terraform init run: | cd terraform/environments/dev \ && echo -e "terraform {\n backend \"local\" {\n path = \"./.local-state\"\n }\n}" | tee override.tf \ && terraform init - name: stg terraform init run: | cd terraform/environments/stg \ && echo -e "terraform {\n backend \"local\" {\n path = \"./.local-state\"\n }\n}" | tee override.tf \ && terraform init - name: prod terraform init run: | cd terraform/environments/prod \ && echo -e "terraform {\n backend \"local\" {\n path = \"./.local-state\"\n }\n}" | tee override.tf \ && terraform init - name: Cache plugin dir uses: actions/cache@v3 with: path: ~/.tflint.d/plugins key: ${{ matrix.os }}-tflint-${{ hashFiles('.tflint.hcl') }} - name: Detect TFlint version run: | printf "TFLINT_VERSION=%s" $(cat aqua.yaml | grep "terraform-linters/tflint" | awk -F '@' '{print $2}') >> $GITHUB_ENV - name: Setup TFLint uses: terraform-linters/setup-tflint@v4 with: tflint_version: ${{ env.TFLINT_VERSION }} github_token: ${{ secrets.GITHUB_TOKEN }} - name: Show version run: tflint --version - name: Init TFLint run: tflint --init -c ./terraform/.tflint.hcl - name: Run TFLint run: tflint --recursive -c $(realpath ./terraform/.tflint.hcl) -f compact
おわりに
今回は対応しなかったですが、reviewdog という OSS を使うと修正箇所がプルリクエストのコメントとして生成されるようです。
https://github.com/reviewdog/action-tflint
TFLint を入れたことで、より効率的に Terraform の運用を行えるようになったと思います。
TFLint ではルールセット自体のバージョンアップも大事ですので、セキュリティチェックの Trivy の導入に加えバージョンアップを自動化してくれるツールである renovate の導入も進んでいますのでそちらも別の記事で紹介していきます!