よくありそうな話ですが、どうするのがスマートか悩む場面がありましたので書きます。
シナリオ
hogeパッケージがインストールされていない時だけ、something.shを実行する
テスト環境
ansible実行環境
Amazon Linux AMI release 2017.09
ansible 2.4.2.0
python version = 2.6.9 (unknown, Nov 2 2017, 19:21:21) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]
リモートホスト(ansibleで操作するホスト)
Amazon Linux AMI release 2017.09
パターン1
インストール状況をrpmコマンドで確認する
- shell: rpm -qa | grep hoge
register: hoge_is_installed
ignore_errors: True
changed_when: False
- shell: /path/to/something.sh
when: hoge_is_installed.stdout == ""
講評
- 少なくともこのansibleのバージョンでは、以下のようなWARNINGが出力されるのが嫌だ
TASK [hoge : command] ***************************************************************************
[WARNING]: Consider using yum, dnf or zypper module rather than running rpm
ok: [xxx.xxx.xxx.xxx]
- スマート度32点(所感)
パターン2
rpmの代わりにパッケージマネージャ使ってねということなので、yumモジュールで対応する
- yum:
list: hoge
register: hoge_package_info
- shell: /path/to/something.sh
when: hoge_package_info.results | selectattr("yumstate", "match", "installed") | list | length == 0
補足説明
- 上記の
hoge_package_info
変数の中身は以下のようになる(例としてcurlパッケージの場合)
ok: [xx.xx.xx.xx] => {
"hoge_package_info": {
"changed": false,
"failed": false,
"results": [
{
"arch": "x86_64",
"envra": "0:curl-7.53.1-14.81.amzn1.x86_64",
"epoch": "0",
"name": "curl",
"release": "14.81.amzn1",
"repo": "installed",
"version": "7.53.1",
"yumstate": "installed"
},
{
"arch": "x86_64",
"envra": "0:curl-7.53.1-16.84.amzn1.x86_64",
"epoch": "0",
"name": "curl",
"release": "16.84.amzn1",
"repo": "amzn-main",
"version": "7.53.1",
"yumstate": "available"
}
]
}
}
講評
- スマート度60点(所感)
-
selectattr
を使うために、実行環境側にjinja2が入っていなければ別途インストールが必要(今回の環境であればyum install python-jinja2
等)- ansibleを実行するための環境構築、みたいな世界がちょっと嫌だ
- pythonとansibleだけあればサッと動くようにしておきたい気持ち
終わりに
どちらかというとパターン2のほうがWARNINGも出ずansibleの推奨に沿っているように思われる、かつ比較的スマートかなと思います。
でもできればスマート度80点以上くらいを目指したいですね。
いい方法をご存知の方がいたら教えていただけると嬉しいです。
参考文献
yum - Manages packages with the yum package manager — Ansible Documentation
[ansible] Check via the yum module and a registered value if a package is installed or not · GitHub