ansible-lint によるチェック機能
『Ansible構築・運用ガイドブック インフラ自動化のための現場のノウハウ』の4章で ansible-lint で Playbook のチェックが行えるとなっています。書籍では、ansible-lint を使って、実際にチェックするところまでを書いています。
個人的に、Playbook を修正し、挙動が変わるか確認したかったため、ここに記載します。
要約
- ansible-lint は、推奨されている Playbook の書き方を提案する
- ansible-lint は、構文のチェックはしない
修正前の Playbook と実行結果
修正前の Playbook と実行結果は以下の通りです。
---
- hosts: all
vars:
ansible_become: yes
ansible_become_method: sudo
tasks:
- name: Install Nginx
block:
- yum:
name: nginx
state: latest
rescue:
- debug:
msg: "Error!"
always:
- debug:
msg: "Always run this section"
[vagrant@localhost chapter4]$ ansible-lint nginx_install.yml
[403] Package installs should not use latest
nginx_install.yml:9
Task/Handler: yum state=latest name=nginx __file__=nginx_install.yml __line__=10
[502] All tasks should be named
nginx_install.yml:9
Task/Handler: yum state=latest name=nginx __file__=nginx_install.yml __line__=10
実行結果の意味
ansible-lint の default rules に詳細な意味が書いてます。
- [403] Package installs should not use latest
Defalut Rules では、
Package installs should use state=present with or without a version
となっており、 version の有無にかかわらず state=present を使うべきだと記載があります。
書籍では version を指定することが推奨されていると説明されていました。
- [502] All tasks should be named
Defalut Rules では、
All tasks should have a distinct name for readability and for --start-at-task to work
すべてのタスクは、読む込み可能かつ --start-at-task が機能するための、個別の名前を持つべきだと記載があります。
書籍では名前を指定されていないタスクがあり、修正すればよいと説明されてました。
Playbook を修正する(1回目)
---
- hosts: all
vars:
ansible_become: yes
ansible_become_method: sudo
tasks:
- name: Install Nginx
block:
- name: Install Nginx in block
yum:
name: nginx
state: 1.16.1
rescue:
- debug:
msg: "Error!"
always:
- debug:
msg: "Always run this section"
[vagrant@localhost chapter4]$ ansible-lint nginx_install.yml
[vagrant@localhost chapter4]$ ansible-playbook -i hosts nginx_install.yml --check
PLAY [all] *********************************************************************************
TASK [Gathering Facts] *********************************************************************
ok: [localhost]
TASK [Install Nginx in block] **************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "value of state must be one of: absent, installed, latest, present, removed, got: 1.16.1"}
TASK [debug] *******************************************************************************
ok: [localhost] => {
"msg": "Error!"
}
TASK [debug] *******************************************************************************
ok: [localhost] => {
"msg": "Always run this section"
}
PLAY RECAP *********************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=1 ignored=0
[vagrant@localhost chapter4]$
ansible-lint では問題ないとされていましたが、Dry Run では state の指定の仕方が違うと表示されました。
fatal: [localhost]: FAILED! => {"changed": false, "msg": "value of state must be one of: absent, installed, latest, present, removed, got: 1.16.1"}
と、なっているため、 name: nginx-1.16.0, state: present を指定します。
Playbook を修正する(2回目)
- hosts: all
vars:
ansible_become: yes
ansible_become_method: sudo
tasks:
- name: Install Nginx
block:
- name: Install Nginx in block
yum:
name: nginx-1.16.0
state: present
rescue:
- debug:
msg: "Error!"
always:
- debug:
msg: "Always run this section"
上記のように修正し、実際に yum で古いバージョンの Nginx が使えるように事前準備します。準備の手順は、ここを参考にしました。念のため、確認すると、
[vagrant@localhost chapter4]$ yum --showduplicates list nginx
(中略)
nginx.x86_64 1:1.16.1-1.el7 @epel
Available Packages
(中略)
nginx.x86_64 1:1.16.0-1.el7.ngx nginx-stable
nginx.x86_64 1:1.16.1-1.el7 epel
nginx.x86_64 1:1.16.1-1.el7.ngx nginx-stabl
yum でインストール可能な Nginx のバージョンの一覧が表示されました。
ansible-lint と Dry Run を実行してみます。
[vagrant@localhost chapter4]$ ansible-lint nginx_install.yml
[vagrant@localhost chapter4]$ ansible-playbook -i hosts nginx_install.yml --check
PLAY [all] *********************************************************************************
TASK [Gathering Facts] *********************************************************************
ok: [localhost]
TASK [Install Nginx in block] **************************************************************
changed: [localhost]
TASK [debug] *******************************************************************************
ok: [localhost] => {
"msg": "Always run this section"
}
PLAY RECAP *********************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[vagrant@localhost chapter4]$
ansible-lint ではエラーが表示されなくなり、古いバージョンの Nginx に変更するため、 PLAY RECAP には change=1 となりました。
触っていて、分からなかったこと
- state=present
インストールの状態を維持することを指定していると意味に気づくのに時間がかかりました。 - --start-at-task
ansibleplaybook コマンドで指定できるオプション。指定したタスク名のところから実施できる。 - playbook の書き方 (name の位置とversionの指定)
公式の yum モジュールの name の指定の仕方は以下の通りです。
A package name or package specifier with version, like name-1.0.
したがって、 name=nginx-1.16.0 と記載しました。
name の位置は、いくつかの Playbook を参考に、感覚的に修正してます。 - ansible-lint では、typo を検知してくれなかったこと
state=least と打ち間違えをしましたが、 ansible-lint では構文のエラーを拾ってくれませんでした。
後に Dry Run 後に構文のエラーが出力されたため修正しました。
参考文献
- 八木澤 健人(2019)『Ansible構築・運用ガイドブック インフラ自動化のための現場のノウハウ』,株式会社マイナビ出版,P80-81
- Nginx - Installation instructions - RHEL/CentOS
- CentOSにちょっと古いバージョンのNginxをインストールする
- Ansible - playbooks_intro