全Terraformユーザーにおすすめしたいtfsec

全Terraformユーザーにおすすめしたいツール、それが **[tfsec](https://tfsec.dev/)** ！！
[Technology Radar](https://www.thoughtworks.com/radar/tools?blipid=202005105)でも取り上げられてるので、最近知名度は上がってきたのでご存知の方は多いのではないでしょうか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214526/2ec3d1d2-04e7-4187-e448-a4c96d0ef60f.png)


## tfsecとは？
Terraformコードの静的解析ツールです。
https://tfsec.dev/
セキュリティ的にベストプラクティスに反している点などを指摘してくれます。
AWS, GCP, Azureのリソースに対応しています。
（以降は特にAWSでの利用について述べます）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214526/34fc65b2-8cd3-1a76-1626-80c82a51204a.png)


## おすすめする理由
こんな経験ないでしょうか？

SecurityHub導入してAWSのベストプラクティスに則っていくぞ！
→ 「RDSを暗号化しましょう」
→ 「既存のRDSを暗号化するにはスナップショットから再作成する必要があります」
→ メンテナンス入れてサービス止めないと対応できない！！
→ なんで初期構築時に暗号化してなかったんだ！！


こんな人におすすめ

- 既存のRDSが暗号化されていなくて絶望したことがある人
- **安価に**PaaSのセキュリティを高めたい人
- セキュリティ対策を勉強したい人

逆に、手動でマネジメントコンソールから作ったリソースに対しては無力です。
そういった実リソースの検知はSecurityHub等を利用しましょう。
令和の時代にIaCしてないエンジニアはいないと思いますが。

## 使い方
### インストール
brewでインストールするか[リリースページ](https://github.com/tfsec/tfsec/releases)からバイナリを取得しましょう。

```console
$ brew install tfsec
```

### コード
このようなS3バケットのリソースがあったとします。

```hcl
resource "aws_s3_bucket" "my-bucket" {
  acl = "public-read"
}
```

### 実行結果

`tfsec` コマンドを実行すると、3件検出されました。
検出されたエラーは以下の通りです。

- [AWS001](https://tfsec.dev/docs/aws/AWS001/): バケットがpublicになっている。
- [AWS002](https://tfsec.dev/docs/aws/AWS002/): バケットのロギング設定が無い。
- [AWS017](https://tfsec.dev/docs/aws/AWS017/): バケットが暗号化されていない。

セキュリティのベストプラクティスに準拠していない点が指摘されますね。

```console
 $ tfsec

Problem 1

  [AWS001][WARNING] Resource 'aws_s3_bucket.my-bucket' has an ACL which allows public access.
  /tmp/tfsec/s3.tf:2

       1 | resource "aws_s3_bucket" "my-bucket" {
       2 |   acl = "public-read"
       3 | }
       4 |

   See https://tfsec.dev/docs/aws/AWS001/ for more information.

Problem 2

  [AWS002][ERROR] Resource 'aws_s3_bucket.my-bucket' does not have logging enabled.
  /tmp/tfsec/s3.tf:1-3

       1 | resource "aws_s3_bucket" "my-bucket" {
       2 |   acl = "public-read"
       3 | }
       4 |

   See https://tfsec.dev/docs/aws/AWS002/ for more information.

Problem 3

  [AWS017][ERROR] Resource 'aws_s3_bucket.my-bucket' defines an unencrypted S3 bucket (missing server_side_encryption_configuration block).
  /tmp/tfsec/s3.tf:1-3

       1 | resource "aws_s3_bucket" "my-bucket" {
       2 |   acl = "public-read"
       3 | }
       4 |

   See https://tfsec.dev/docs/aws/AWS017/ for more information.

  times
  ------------------------------------------
  disk i/o             1.009268ms
  parsing HCL          13.505µs
  evaluating values    126.152µs
  running checks       459.172µs

  counts
  ------------------------------------------
  files loaded         1
  blocks               1
  evaluated blocks     1
  modules              0
  module blocks        0

3 potential problems detected.

```

## GitHub Actionsで実行する
毎回手動で実行してもいいのですが、**人間絶対に忘れます**。
当然、CIで実行したいと思うでしょう。

tfsecを実行してくれるActionsはいくつか公開されています。
https://github.com/marketplace?type=actions&query=tfsec

私は[terraform-security-scan](https://github.com/marketplace/actions/terraform-security-scan)を利用することが多いです。

以下のActionsの設定でPull Requestに対してActionsで `tfsec` を実行できます。
警告があった場合はPull Requestにコメントが投稿されます。

```yaml:.github/workflows/tfsec.yml
name: tfsec

on: [pull_request]

jobs:
  tfsec:
    name: tfsec
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Terraform security scan
        uses: triat/terraform-security-scan@v2.1.0
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```


## Vimで実行する
Actionsで実行されるからと言って、手元で実行しないということはありません。
手元でサクッと実行して確認したいですよね？

私はNeovimを使用しているのですが、こういった解析ツールはターミナルからではなくNeovim上で実行することが多いです。
`tfsec`に関してもtfファイル編集中に実行エディタ上で実行したいのですが、あいにくpluginが存在しませんでした。

なので、自作しました！
<a href="https://github.com/reireias/vim-tfsec"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/reireias/vim-tfsec.png" width="460px"></a>

![Peek 2021-02-10 00-39.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214526/c5d1b4f5-3c48-a580-f3c1-54f6c2fee9be.gif)

検出したエラーをQuickfix Listに追加しているので、Quicklistの操作で次のエラーに移動できます。

## tfsecで検出できないもの
冒頭でも述べましたが手動で作成したリソースなどには無力です。
また、Terraformで管理しない（できない）リソースに対するセキュリティ警告は検出できません。
たとえば、「rootアカウントにはMAFデバイスを設定する」等の検出はできません。

上記を検出するためには[SecurityHub](https://aws.amazon.com/jp/security-hub/)を利用することを推奨します。
SecurityHubは企業で利用するAWSアカウントだったら必ず設定すべき項目だと個人的には思います。

## まとめ
tfsecはプロジェクト初期から是非導入することをおすすめします！！