😎

tflint のカスタムルールを GitHub にホスティングしインポートする方法

2023/08/14に公開

はじめに

Terraform の lint ツールである tflint にカスタムルールを追加し、それを GitHub 上にホスティングしインポートする手順を紹介します。

GitHub 上へのホスティングとそこからのインポート方法は公式の GitHub リポジトリの README や解説記事に断片的に記載されていましたが、手順を最初から最後まで順を追って説明している情報がなかったため、備忘録を兼ねてこの記事を書きました。

手順

① カスタムルールのテンプレートリポジトリを元にリポジトリを新規作成

tflint-ruleset-template リポジトリをテンプレートにしてリポジトリを新規作成します。

リポジトリができました。

② カスタムルールの実装を記述

今回はホスティング方法を説明したいだけなため tflint-ruleset-template リポジトリのカスタムルールの実装をそのまま使います。

カスタムルールの実装とテストの書き方については同リポジトリの example を見れば書けると思います。

③ 鍵を作成

カスタムルールを配信するためにはビルドしたバイナリに署名をする必要があります。
そのため Terraform の下記ドキュメント通りに鍵を作成します。
https://developer.hashicorp.com/terraform/tutorials/providers/provider-release-publish#generate-gpg-signing-key

③-1 gpg のインストール

$ brew install gpg

③-2 主鍵の作成

$ gpg --full-generate-key

ここからは対話式に情報を入力していきます。

1 を入力してください。

ご希望の鍵の種類を選択してください:
   (1) RSA と RSA
   (2) DSA と Elgamal
   (3) DSA (署名のみ)
   (4) RSA (署名のみ)
   (9) ECC (署名と暗号化) *デフォルト
  (10) ECC (署名のみ)
  (14) カードに存在する鍵

4096 を入力してください。
※ 4096 でなくとも任意の長さで構いません

RSA 鍵は 1024 から 4096 ビットの長さで可能です。
鍵長は? (3072)

有効期限なしで良い場合はそのまま Enter を押します。
※ 有効期限を設定したい場合はメッセージに従って任意の入力をしてください

鍵の有効期限を指定してください。
         0 = 鍵は無期限
      <n>  = 鍵は n 日間で期限切れ
      <n>w = 鍵は n 週間で期限切れ
      <n>m = 鍵は n か月間で期限切れ
      <n>y = 鍵は n 年間で期限切れ
鍵の有効期間は? (0)

y を入力してください。

これで正しいですか? (y/N)

ユーザー ID を作成するために任意の名前を入力してください。
この例では hoge taro を名前として設定します。

GnuPGはあなたの鍵を識別するためにユーザIDを構成する必要があります。

本名:

ユーザー ID を作成するために任意のメールアドレスを入力してください。
この例では hoge_taro@example.com をメールアドレスとして設定します。

電子メール・アドレス:

必要な場合はコメントを入力してください。
この例ではコメントは設定しません。

コメント:

O を入力してください。

名前(N)、コメント(C)、電子メール(E)の変更、またはOK(O)か終了(Q)?

任意のパスフレーズを設定してください。
パスフレーズはあとで利用するので控えておいてください。

新しい鍵を保護するために、
パスフレーズを入力してください。
パスフレーズ:
<OK>                <キャンセル(C)>

鍵が作成され下記のようなメッセージが表示されます。
この例の場合、uid の行にある hoge taro <hoge_taro@example.com> がユーザー ID になります

gpg: /Users/test/.gnupg/trustdb.gpg: 信用データベースができました
gpg: ディレクトリ'/Users/test/.gnupg/openpgp-revocs.d'が作成されました
gpg: 失効証明書を '/Users/test/.gnupg/openpgp-revocs.d/XXXXXXXX.rev' に保管しました。
公開鍵と秘密鍵を作成し、署名しました。

pub   rsa4096 2023-08-14 [SC]
      XXXXXXXXXXXXXXXXXXXXXXXXXX
uid                      hoge taro <hoge_taro@example.com>
sub   rsa4096 2023-08-14 [E]

これで主鍵の作成は完了です。

③-2 公開鍵の作成

先ほどのユーザーIDを指定してください。
-----BEGIN PGP PUBLIC KEY BLOCK----- から -----END PGP PUBLIC KEY BLOCK----- を控えておいてください。

$ gpg --armor --export "ユーザーID"

-----BEGIN PGP PUBLIC KEY BLOCK-----

mQINBGB91soBEACp/u6jJZAKeVahHGtR6jzDFcOvivhUFV2fuwBBW/jxqYrWEeEX
+rny8oChQjCABHG9bUxhSSqPyfCK/kUI3VK8Qrxpby6dQgqOFuF61P1mBI0BppLF
JGydv8J9SIIbYJOyajFzMLrvL+xvKD1AblRFBtQke8ts+gz9B+oW7SmAVMb3gM4n
 …
-----END PGP PUBLIC KEY BLOCK-----

③-3 秘密鍵の作成

先ほどのユーザーIDを指定してください。
パスフレーズの入力が求められるので先ほどのパスフレーズを入力してください。

-----BEGIN PGP PRIVATE KEY BLOCK----- から -----END PGP PRIVATE KEY BLOCK----- を控えておいてください。

$ gpg --armor --export-secret-keys "ユーザーID"

-----BEGIN PGP PRIVATE KEY BLOCK-----

lQdFBGB91soBEACp/u6jJZAKeVahHGtR6jzDFcOvivhUFV2fuwBBW/jxqYrWEeEX
+rny8oChQjCABHG9bUxhSSqPyfCK/kUI3VK8Qrxpby6dQgqOFuF61P1mBI0BppLF
JGydv8J9SIIbYJOyajFzMLrvL+xvKD1AblRFBtQke8ts+gz9B+oW7SmAVMb3gM4n
 …
-----END PGP PRIVATE KEY BLOCK-----

④ GitHub Actions の Secret に秘密鍵とパスフレーズを登録

GitHub Actions によってビルドを行い、GitHub リリースのアセットにビルド成果物をアップロードするので、GitHub Actions の Secret に秘密鍵とパスフレーズを登録します。

Secret はテンプレートリポジトリをコピーして新規作成したリポジトリに設定します。

「Settings」 => 「Secret and Variables」 => 「New repository secret」 から登録できます。

GPG_PRIVATE_KEY という変数に先ほどの秘密鍵を設定します。
PASSPHRASE という変数に先ほどのパスフレーズを設定します。

⑤ GitHub Actions の実行

GitHub Actions を実行し、GitHub リリースのアセットにビルド成果物をアップロードします。

tag が作成されたときにビルド成果物をアップロードする GitHub Actions のため、テンプレートをコピーした自身のリポジトリで 「Create new release」 からタグを新規作成してください。

タグを作成しました。

タグが作成されたことで GitHub Actions が実行されます。

実行完了するとビルド成果物がタグ assets にアップロードされます。

⑥ カスタムルールのインポート

tflint を実行するディレクトリに .tflint.hcl を作成し、下記を記載します。

  • プラグイン名(plugin "hoge"の部分): go の module 名の tflint-ruleset-ほにゃらら の ほにゃららの部分
    • プラグイン名を変える場合は module 名を変えて再度タグを作成し、GitHub Actions を実行してください。
    • module 名は tflint-ruleset-ほにゃらら という形式である必要があります
  • version: GitHub に作成したタグのバージョン名
  • source: リポジトリ名
  • 公開鍵: 作成した公開鍵
plugin "hoge" {
  enabled = true

  version = "0.1.0"
  source  = "github.com/example/tflint-ruleset-hoge"

  signing_key = <<-KEY
  -----BEGIN PGP PUBLIC KEY BLOCK-----
  mQINBGCqS2YBEADJ7gHktSV5NgUe08hD/uWWPwY07d5WZ1+F9I9SoiK/mtcNGz4P
  JLrYAIUTMBvrxk3I+kuwhp7MCk7CD/tRVkPRIklONgtKsp8jCke7FB3PuFlP/ptL
  SlbaXx53FCZSOzCJo9puZajVWydoGfnZi5apddd11Zw1FuJma3YElHZ1A1D2YvrF
  ...
  KEY
}

init し、カスタムルールをインポートします。

$ tflint --init
Installing `hoge` plugin...
Installed `hoge` (source: github.com/example/tflint-ruleset-hoge, version: 0.1.0)

--version をするとカスタムプラグイン ruleset.template (0.1.0) がインポートされたことがわかります。
今回はテンプレートリポジトリの実装内容を変更していないのでルールセット名が template になっています。
main.go の Name がルールセット名になります。

$ tflint --version
TFLint version 0.47.0
+ ruleset.template (0.1.0)
+ ruleset.terraform (0.4.0-bundled)

補足

  • 今回は Public リポジトリからのインポートのためリポジトリへのアクセスに関して認証を気にする必要がありませんでした。GitHub Actions 上での tflint 実行に限りますが自身にアクセス権限のある Private リポジトリからのインポートは setup-tflint actionsで GITHUB_TOKEN を指定すればおそらくできます。
    - name: Init TFLint
      run: tflint --init
      env:
        GITHUB_TOKEN: ${{ github.token }}

参考文献

https://developer.hashicorp.com/terraform/tutorials/providers/provider-release-publish#generate-gpg-signing-key
https://github.com/terraform-linters/tflint-ruleset-template
https://github.com/terraform-linters/setup-tflint
https://qiita.com/neruneruo/items/e3c2957d44e6f1d00f5c
https://tech.kanmu.co.jp/entry/2022/03/01/100717

Discussion