Ansibleでyum moduleを使っていたときに少しハマったのでメモします。
yum - Manages packages with the yum package manager — Ansible Documentation
yum moduleとは
その名の通り、RedHat系で利用されるパッケージ管理システムを利用してプロビジョニングを行うためのモジュールです。
このmoduleを利用して、パッケージをインストールしたり削除したりします。
各stateの一覧と意味
公式ドキュメントの state 欄にも
Whether to install (
presentorinstalled,latest), or remove (absentorremoved) a package.
としか書かれておらず、結局それぞれの違いはなんだろうと思ったのがきっかけです。
| state | 意味 | 対応するyumコマンド |
|---|---|---|
present |
パッケージのインストール | yum install |
installed |
presentのalias |
yum install |
latest |
パッケージの最新版へのアップデート | yum update |
absent |
パッケージのアンインストール | yum remove |
removed |
absentのalias |
yum remove |
注意すること
このうち、 latest が曲者でした。ansible実行の1回目と2回目以降で、結果が変わるケースがあります。
-
nameで[pkgname]-[version]を指定したとしても、stateがlatestであれば、指定したバージョンより新しいものが(あれば)インストールされる - しかも、新しいバージョンがインストールされるのはansible実行の2回目以降。1回目は指定したバージョンがインストールされる
例えば、以下のような書き方をしたとします。
name: install one specific version of Apache
yum: name=httpd-2.2.29-1.4.amzn1 state=latest
yumリポジトリ上に、 httpdの2.2.29と、2.2.31のパッケージが混在していたとします。
すると、以下のような動きになります。
- 初回実行時 : httpd-2.2.29がインストールされます。
- 2回目以降 : httpd-2.2.31へ更新されます。
何が嫌か
冪等性が崩れます。何回やっても同じ結果になるかと思いきや、初回と2回目以降で結果が変わるためです。
試したのはansible 1.9ですが、ソースコードを見る限りでは2.0系でも同じようです。
https://github.com/ansible/ansible-modules-core/blob/stable-1.9/packaging/os/yum.py
https://github.com/ansible/ansible-modules-core/blob/stable-2.0/packaging/os/yum.py
結局どうするべきか
パッケージのバージョンを固定したければ、そもそもlatestを使わずに、presentかinstalledを使う ということでした。
裏でどんなyumコマンドが実行されているかを想像した上で、latest っていう意味から分かるでしょと言われるとそうなのですが、何気なく書く場合は注意しましょうという話でした。