VimmerがCloudFormationを書くなら ale + cfn-python-lint が便利！

Vimmer ですか？
AWS CloudFormation を書いてますか？
では `ale` と `cfn-python-lint` を使いましょう :thumbsup: 

# どう便利なの？

見た方が早いと思うので、試しに壊れたCloudFormationテンプレートファイルを vim で開いてみます。

```yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Sample template for ale.vim and cfn-python-lint

Parameters:
  # このパラメータは使われてない
  ThisIsNotUsed:
    Type: String

Resources:
  EC2Instance:
    Type: 'AWS::EC2::Instance'
    # 必須パラメータが未定義
    Properties:
      # AvailabilityZone のハードコーディングは避けるべし
      #   ≒  Parameterや Fn::GetAZs を使おう
      AvailabilityZone: 'us-west-2a'
      Tags:
        - Key: Name
          # 未定義パラメータを使用している
          Value: !Sub "${UndefinedParameter}"

Outputs:
  Sample:
    # 未定義リソースを使用している
    Value: !Ref NoExistResoure
```

私の vim だと次のような表示になります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/27201/512e6a60-fc97-bbec-07ca-3bd9dfe17e42.png)

`>>` とか `--` のある行にカーソルを合わせると vim のステータスラインにメッセージが表示されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/27201/6523b6cc-62e3-99ab-cd74-284f649bc0d9.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/27201/25a5a7ce-586a-6278-e9ed-707dae9c4c21.png)

`ImageId` か `LaunchTemplate` が必須だよ、と教えてくれています。ありがとう。

# ale とは

[ale](https://github.com/w0rp/ale) は Vim(8.0以上)/NeoVim 向けの Asynchronous Lint Engine プラグインです。
`rubocop` や `eslint` など各種 Linter と連携して Lint の結果を Vim 上に表示することができます。

似たプラグインに [syntastic](https://github.com/vim-syntastic/syntastic) がありますが、 `ale` は `vim8` の `job` に対応しているので非同期処理される・`neovim` にも対応している・`vador` によるテストが充実している、などと後発らしい特徴があります。
同じく後発のプラグインとして [neomake](https://github.com/neomake/neomake) もあるようですが、私は `ale` しか使ったことがないので詳しく知りません...。

# cfn-python-lint とは

[cfn-python-lint](https://github.com/awslabs/cfn-python-lint) は `awslabs` で作られているPython製のCloudFormation Linter です。 2018/04 に公開されたばかりのできたてホヤホヤです。

既存の Linter としては、　NodeJS製の `[cfn-lint](https://github.com/martysweet/cfn-lint)` がありましたが、こちらは出力結果がとても人間に優しく、そして機械には優しくない（パースしづらい）ものでした。

`cfn-python-lint` は [ansible-lint](https://github.com/willthames/ansible-lint) を参考にして実装されているようで [^1] 機械にも優しい出力ができるようになっています。

[^1]: https://github.com/awslabs/cfn-python-lint#credit

# 設定方法

## 私の環境

筆者の環境は次の通りです。

- OS: macOs HighSierra 10.13.5
- Vim: 8.1.10 (macvim)
- Python: 3.6.5
    - cfn-lint: 0.4.1

## [python] cfn-python-lint をインストールする

`cfn-python-lint` は `pip` でインストールできます。
GitHub上のリポジトリは `cfn-python-lint` だけど `pip` でインストールする時は `cfn-lint` なことに注意です。[^2]

```bash
pip install cfn-lint
```

[^2]: コマンド名も `cfn-lint` なのだけど Node.js製の `cfn-lint` と被せたのはわざとなのかどうなのか...

## [vim] ale をインストールする

`ale` をインストールします。
例えば [dein.vim](https://github.com/Shougo/dein.vim) でプラグインを管理しているなら、

```vim
call dein#add("w0rp/ale")
```

といった感じです。
私は TOML を利用しているので、

```toml
[[plugins]]
repo = "w0rp/ale"
```

という具合です。

## [vim] filetype=cloudformation を設定する

`cfn-python-lint` を `ale` で利用するには `filetype` を `cloudformation` にする必要があります。
`filetype` が `cloudformation` なら `ale` は自動的に `cfn-python-lint` を使います。

私の場合は、 `xxxx.template.yaml` というファイル名にすることが多いので `~/.vim/ftdetect/cloudformation.vim` に次のように設定しています。

```vim
au BufRead,BufNewFile *.template.yaml set ft=cloudformation.yaml
```

`yaml` をベースにしつつ `fieltype` を `cloudformation` にすることで、 `yaml` のシンタックスハイライトを利用しつつ `ale` で `cfn-python-lint` を使うことができるようになります。

# 備考

ちなみに `ale` で `cfn-python-lint` を使えるようにしたのは私です :smirk:
ちなみにその直後、 `cfn-python-lint` を最新版にすると動かないからと修正されました :innocent: