見出し画像

Ansible LintによるPlaybookのチェック方法


こんにちは、株式会社SHIFT、自動化エンジニアの水谷です。

AnsibleのPlaybookはYAML形式のテキストファイルなのですが、同じ目的のPlaybookを記述するにしても、書く人によっては使うモジュールが違ったり、細かい表記方法が異なることがよくあります。期待通り動けばそれで良い、という考え方もありますが、後々のメンテナンスや、グループ内外で再利用することを考えると、記述方法がある程度統一されていたほうが良いでしょう。また、なるべくバグを生まない(生みにくい)記述方法で書いていくことは、最終的には全体の工数を削減するポイントになったりもします。

一般的にコードの静的解析ツールを“lint”と呼んだりしていて、いろいろなプログラム言語用のlintがあるのです、実はAnsibleにもこれが用意されています。Ansible用のlintは、 “Ansible Lint”と呼ばれており、これを使えばPlaybookの記述に怪しいところがないかを調べたり、決めたルールに従って書かれているかどうかをチェックしたりできます。

今回はそのAnsible Lintについて書いてみたいと思います。

Ansible Lintのインストール方法

まずは、Ansible Lintをインストールしましょう。インストールはpipで簡単にできます。Ansibleがすでにインストールされている環境であれば、pipも入っているはずですから、エラーになることも少ないでしょう。 

​pip install ansible-lint
画像1

インストールが終了したら、念のためバージョン表示をさせて、Ansible Lintが動作することを確認しましょう。

ansible-lint --version 

Ansible Lintの使い方

Ansible Lintの一番簡単な使い方は、引数にPlaybookのファイルパスを指定して実行するだけです。これで、約30項目のデフォルトチェック項目でPlaybookをチェックしてくれます。

簡単な例として、下のようなPlaybook(ファイル名はsite.yml)をチェックしてみます。

---
- name: test ansible
 hosts: all
 gather_facts: no
 tasks:
 - name: copy a file
   win_copy:
     src: "{{ filename1}}"
     dest: c:\temp\
 - name: copy another file
   win_copy:
     src: "{{ filename2 }}"
     dest: c:\temp\
   when: flag == True

以下のコマンドを実行します。

ansible-lint site.yml 

結果は、このように2つの問題点が指摘されました。

画像2

1つ目は、最初のwin_copyモジュールの呼び出しで、srcに”{{ filename1}}”と指定していますが、よく見ると”1”と”}}”の間にスペースがありません。実際にはスペースが無くても動作するのですが、変数名の前後にスペースを1つ入れることがルールとなっているようです。

2つ目は、“when: flag == True”の行が問題となっています。これは、TrueまたはFalseを持つ変数をwhenで使うときは、TrueやFalseと比較するのではなく、“when: flag”(あるいは“when not flag”)のように記述することがルールになっているからです。

なお、PlaybookがYAMLとして正しく解釈できるか、あるいは存在しないモジュールを使用していないか、などの問題については、“--syntax-check”を付けて実行すれば見つけてくれますので、まずはこちらを実行するべきですね。

ansible-playbook -i hosts site.yml --syntax-check

デフォルトのルール

Ansible Lintのデフォルトルールは、以下のコマンドで表示できます。

ansible-lint -L 

​しかし、これでは内容が分かりにくいので、以下のページで確認するのが良いと思います。
https://docs.ansible.com/ansible-lint/rules/default_rules.html

ルールはAnsible Lintのバージョンが上がるにつれて、増えていきます。現時点(2020年8月)で最新のバージョン4.2.0では、32個のルールがデフォルトで用意されています。

特定のルールの除外方法

場合によっては、すべてのデフォルトルールが適応されてほしくない場合があります。たとえば、上の例であれば、2つ目のチェックは不要という場合、-xコマンドラインオプションの後にルールIDを指定することでこのチェックを除外することができます。

ルールIDは、上で実行した結果に“[601]”と書いてあるこの数字です。また、上のサイトにもIDが書かれています(“E601”などとあるその“601”がID)。

ansible-lint -x 601 site.yml

これで、1つ目のエラーのみが表示されるようになりました。

画像3

また、除外は個々のルールIDだけでなく、ルールタグで指定することもできます。例えば、モジュールに関するルールは4つあり、それぞれ401、402、403、404のIDを持っています。そしてこれらのルールには“module”というタグがついていますので、-x moduleとすることで、これら4つのルールはすべて適応されなくなります。

なお、タグを調べるには、ansible-lint -Tと実行すると、どのタグにどのルールIDが含まれるかが分かります。

また、.ansible-lintというテキストファイルを作成し、以下のように記述しておくことでもルールの除外ができます。毎回コマンドラインで指定するのは面倒ですし、たくさんのルールを除外したい場合は特に、コマンドラインに記述するよりこちらのほうが便利ですね。

skip_list:
 - 601
 - module

.ansible-lintでこまかな調整

先ほど.ansible-lintファイルに除外するルールを記述する方法を書きましたが、このファイルではこれ以外にもAnsible Lintの動作を変更する設定が記述できます。それらを紹介してみたいと思います。

exclude_path:
ルールチェックを除外したいディレクトリを指定します。ここに列挙したディレクトリはチェックされません。

exlude_path:
 - ./roles/dummyrule/
 - ./roles/installChrome/test/

tags:
skip_list:の逆で、適応したいルールをタグで指定します。

tags:
 - idiom
 - module

parseable:
結果を後からパースしやすい1行1結果の形式で表示(出力)します。

parseable: True

これ以外にもまだありますので、詳しくはこちらをご覧ください。
https://docs.ansible.com/ansible-lint/configuring/configuring.html

noqaによるFalse positiveの回避

最後に、静的チェックツールにつきもの(?)の、正しい記述なのにチェックに引っかかってしまうケースへの対応方法を紹介します。

Playbookにおいて、Ansible Lintによるチェックを避けたい行に # noqa [ルールID]を記述しておけばOKです。例えば、上の例でルール601のチェックを受けなくするには、以下のようにします。

 - name: copy another file
   win_copy:
     src: "{{ filename2 }}"
     dest: c:\temp\
   when: flag == True # noqa 601


CI/CDでAnsibleを使って環境構築を行う場合などでは、Playbookを実行する前にAnsible LintでPlaybookをチェックしてから実行すると良いと思います。また、今回は書きませんでしたが、Pythonのコードで独自のルールを作成することもできます。

Ansible Lintは、Ansibleをしっかり使っていく上では、かなり有用なツールですので、Ansibleをガッツリ使っていこうという方は、是非Ansible Lintも合わせて使ってみてください。

――――――――――――――――――――――――――――――――――

執筆者プロフィール:水谷裕一
大手外資系IT企業で15年間テストエンジニアとして、多数のプロジェクトでテストの自動化作業を経験。その後画像処理系ベンチャーを経てSHIFTに入社。
SHIFTでは、テストの自動化案件を2件こなした後、株式会社リアルグローブ・オートメーティッド(RGA)にPMとして出向中。RGAでは主にAnsibleに関する案件をプレーイングマネジャーとして担当している。

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/