What's this?

これは次の Ansible Advent Calendar 2020 に参加して書いている記事となります。 他の方の記事については下記のリンクからたどれますので是非あわせてご参照下さい。

Lint って何?

Lint って何でしょう? Wikipedia に丁度、lint の記事 https://ja.wikipedia.org/wiki/Lint があるようなので見てみましょう。

lint とは、主にC言語のソースコードに対し、コンパイラよりも詳細かつ厳密なチェックを行うプログラムである。静的解析ツールとも呼ばれる。 (中略) コンパイラではチェックされないが、バグの原因になるような曖昧な記述についても警告される。 構文(シンタックス)レベルのチェックだけでなく、意味(セマンティクス)レベルのチェックまで実行するものもある。

ソースコードの静的解析とはソースコードをコンパイル、実行することなく読込み、何らかの解析を行なってチェックすることです。 Ansible と C 言語などプログラム言語のソースコード、どう関係するのだろう? と思われる方もいらっしゃるかもしれませんが、 Ansible Playbook の YAML ファイルも IaC [1] 化された『(ソース) コード』と見做すことができますし、 プログラミング言語の場合と同様に静的解析して同じようなことができそうということは想像できるかと思います。

実際に Ansible Playbook の YAML ファイルを静的解析、チェックするためにいくつか OSS のツールが開発されていてすぐに使うことができます。 Ansible の Lint ツールとして有名な二つについて次の節では簡単に紹介しておきます。

[1]IaC = Infrastructure As Code、詳しくは https://ja.wikipedia.org/wiki/Infrastructure_as_Code などをご参照下さい。

Ansible で使える Lint ツール

Ansible Lint

Ansible Lint は Ansible Playbook などを対象に静的解析を行ない、経験則などに基づいてより良い書き方がなされているかをチェックすることができます。 標準でも最低限必要十分と思われるチェックが可能ですが拡張してチェック項目を増やすこともできます。

yamllint

yamllint は YAML ファイルを対象に静的解析を行ない、経験則などに基づいてより正しく、良い書き方がなされているかをチェックすることができます。 Ansible に特化したものではないですが Ansible Playbook や Role を構成する大部分のファイルは YAML ファイルなので活用できます。

なお yamllint についてはカスタム Rule 実装 (Python コード) を用意してすぐ拡張できるような仕組みは upstream では用意されていませんが、筆者が開発作業中の branch を使えば plugin により拡張可能です。

なぜ Lint が必要?

Ansible Playbook でも Lint ツールがあって色々静的解析できそうということはわかりました。 ではなぜこれらの Lint ツールが必要で、何が嬉しいのでしょうか?

筆者は主に次のようなメリットがあると考え、積極的に Lint ツールの利用をすすめています。 (利用はほぼ必須と考えています。)

  • Ansible Playbook を実行せずに簡単に構文の間違い、ケアレスミスなどをみつけることができる
  • Ansible Playbook を実行せずに簡単により良い Playbook の書き方を教えてもらえる
  • Ansible Playbook を実行せずに簡単に Playbook を確認できて、人によらず一定品質を保つ手助けとできる
  • CI ワークフローの中に簡単に組み込むことができる

例えば Ansible Playbook の中で同じことを行う task であっても色々な書き方で定義することができます。 これ自体は良いことではあるのですが Playbook を複数人で開発、利用していこうとすると非常に問題となります。

例えば httpd を RPM パッケージでインストールする task 定義を書く場合でも色々考えられます [2]

  • shell モジュールを利用 (1):

    - shell: yum install -y httpd
    
  • shell モジュールを利用 (2):

    - name: Ensure httpd package is installed
      shell: yum install -y httpd
    
  • command モジュールを利用:

    - name: Ensure httpd package is installed
      command: yum install -y httpd
    
  • package モジュールを利用 (1):

    - name: Ensure httpd package is installed
      package: name=httpd state=present
    
  • package モジュールを利用 (2):

    - name: Ensure httpd package is installed
      package:
        name: httpd
        state: present
    
  • package モジュールを利用 (3):

    - name: Ensure httpd package is installed
      package:
        name:
          - httpd
        state: present
    
  • yum モジュールを利用:

    - name: Ensure httpd package is installed
      yum:
        name:
          - httpd
        state: present
    

人によって書き方がばらばらだと保守が大変になりますし、すべてのパターンについてきちんとテストする工数も増大します。 Lint ツールによってより良い書き方となっているかをチェックし、ある程度標準化された書き方にそろえていくことで Playbook の品質を上げ、開発保守をより安全に進めることができるようになるわけです。

[2]もし余裕があれば、この例の中でどの書き方が一番良いか、またそれはなぜかを考えてみて下さい。

次回予告

次回以降では実際に Ansible Lint と yamllint をどう使っていくのか実例を示しながら簡単に紹介する予定です。