Ansibleでcommandを使わないためのモジュール
Playbookを書いているとたまに
- 特定のパッケージがインストールされていたらなにかする
- 特定のユーザが存在したらなにかする
みたいな処理をしたいときがあります。
実際にインストールしたりユーザ作成せずに現状の確認だけをしたいケースです。
そういったときに command
, shell
モジュールを使用することで実現できます。
tasks: - name: check if httpd is installed shell: rpm -qa | grep httpd register: httpd_installed ignore_errors: True check_mode: False changed_when: False - name: print debug: msg: "httpd is installed" when: httpd_installed.rc == 0
ただし上記のやり方は色々めんどくさいこともあります。
changed_when
やignore_errors
等のパラメータの設定が必要- ansible実行時やansible-lintでwarningが出力されがち
そこでcommand
モジュールの代わりになりうるモジュールをいくつか紹介します。
検証環境
ansible: v2.9.9
targetOS: CentOS7.7 and Ubuntu 18.04
stat
stat – Retrieve file or file system status — Ansible Documentation
stat
モジュールはファイルの状態を確認できます。
ファイルの有無のみでなく種類(ファイル/ディレクトリ/リンクなど)やowner等の情報も取得できます。
tasks: - name: check if /etc/hosts exists stat: path: /etc/hosts register: etchosts - name: print debug: msg: "/etc/hosts exists" when: etchosts.stat.exists - name: print debug: msg: "/etc/hosts is directory" when: etchosts.stat.isdir # this should be False
package_facts
package_facts – package information as facts — Ansible Documentation
package_facts
はパッケージがインストールされているかの確認ができます。
取得したパッケージ一覧はansible_facts.packages
に格納されます。
tasks: - name: check packages package_facts: manager: auto - name: print debug: msg: "Version of NetworkManager is {{ ansible_facts.packages['NetworkManager'][0]['version'] }}" when: "'NetworkManager' in ansible_facts.packages"
getent
getent – A wrapper to the unix getent utility — Ansible Documentation
getent
モジュールはgetentコマンドのラッパーでpasswdやgroup等のデータを取得できます。
取得した情報はgetent_***
に格納されます(***は指定したdatabase名)
※取得できる情報は対象のOSによって異なります。
tasks: - name: check users getent: database: passwd - name: print debug: msg: "app1 user exists" when: "'app1' in getent_passwd"
service_facts
service_facts – Return service state information as fact data — Ansible Documentation
service_facts
モジュールは各serviceの情報を取得します。
取得した情報はansible_facts.services
に格納されます。
tasks: - name: check services service_facts: - name: print debug: msg: "firewalld is {{ ansible_facts.services['firewalld.service']['status'] }}" when: "'firewalld.service' in ansible_facts.services"
まとめ
たまたまtwitterでpackage_facts
を知って他にも似たようなモジュールが無いか調べたら色々ありました。
モジュールをなるべく使うことでOSの差分を吸収してくれたりコード量も減るのでよりPlaybookらしいPlaybookになる気がします。