Ansibleでyum
モジュールを利用すると、裏側では環境に合わせて以下のいずれかのパッケージマネージャが自動的に選択されます。つまり、Ansible上ではyum
モジュールなんだけど実際にはdnf
がいつの間にか動いているといった自体が発生しますw
- yum
- yum4
- dnf
このままだとdnfが入っていない環境下では利用することができませんし、AWSで頻繁に利用されるAmazon Linuxでは現在もyum
が現役だったりします。困ったw
結論から言うと数行ちょちょいと設定すれば解決します。
エラーの原因
エラーメッセージを見てみます。ここではPython3上でyumモジュールを動かした際に、dnfモジュールが入っていなかったため次のようなエラーメッセージが表示されました。
$ ansible-playbook playbook.yml (中略) fatal: [example.com]: FAILED! => {"changed": false, "msg": "The Python 2 bindings for rpm are needed for this module. If you require Python 3 support use the `dnf` Ansible module instead.. The Python 2 yum module is needed for this module. If you require Python 3 support use the `dnf` Ansible module instead."} $ dnf -bash: dnf: コマンドが見つかりません
Python3からパッケージマネージャを利用する場合は、強制的にdnfモジュールが利用されるよう変更があったようです。Python2であればyumで動作させることが可能みたいですね。なんてこった\(^o^)/
対処方法
A. Python2で動かす - use_backend
まずはPython2で動作させる方法を試してみます。接続情報を書いたInventory用のファイルのansible_python_interpreter
にPython2のパスを絶対パスを書きます。
[servers] exmaple.com [servers:vars] ansible_port=22 ansible_ssh_user=ansibleman ansible_ssh_private_key_file=~/.ssh/id_rsa # ansible_python_interpreter=/usr/bin/python3 ansible_python_interpreter=/usr/bin/python
Playbook上でyumモジュールのオプションとしてuse_backend
を指定します。
- hosts: servers remote_user: ansibleman become: yes tasks: #-- Apacheをインストール --# - name: Install Apache yum: name: httpd state: present use_backend: yum
use_backend
はAnsible2.7から追加されたオプションで、裏側で動かすパッケージマネージャをこちらで指定することができます。
引数 | デフォルト |
---|---|
auto | ★ |
yum | |
yum4 | |
dnf |
これで解決はします…しますがPython2にバージョンを下げるのはちょっと気持ち悪いですよね。後述しますがサポート終了が迫っているPython2を使い続けるのはリスクが高いですし、困った困った。
B. Python2で動かす - ansible_facts
Ansibleにはシステム全体で利用するグローバル変数のような物が用意されており、必要に応じてPlaybookなどから利用することができます。これをFact
と呼びます。
Factに何が設定されているかは次のコマンドですべて表示することができます。servers
の部分はInventoryに記載したサーバをグルーピングした際の名前を指定してください。原理としては、このFactの中にあるパッケージマネージャのデフォルト設定がdnf
になっているのを、無理やりyum
に書き換えてしまえば良いという少々強引な方法ですw
$ ansible servers -m setup example.com | SUCCESS => { "ansible_facts": { (中略) "ansible_pkg_mgr": "dnf",
まずInventoryのファイルはPython2を指すようにしておきます。
[servers] exmaple.com [servers:vars] ansible_port=22 ansible_ssh_user=ansibleman ansible_ssh_private_key_file=~/.ssh/id_rsa # ansible_python_interpreter=/usr/bin/python3 ansible_python_interpreter=/usr/bin/python
Playbookは以下の通り。冒頭のset_fact
でFactを強制的にyum
へ書き換えています。あくまでこのタスクを実行するときだけの変更です。恒久的に変更されるわけではないので他のPlaybookへの影響は心配しなくても大丈夫です。
- hosts: servers remote_user: ansibleman become: yes tasks: - set_fact: ansible_facts: pkg_mgr: yum #-- Apacheをインストール --# - name: Install Apache yum: name: httpd state: present
こちらも先ほどの例と同様にPython2に下げる必要があり、気持ち悪さが残ります。
C. Python3で動かせる…?
Ansibleのyumモジュールの公式ドキュメントによると、冒頭にある文章の通りです。
This module only works on Python 2. If you require Python 3 support see the dnf module.
「このモジュールはPython2でのみ動作します。Python3はdnfモジュールを参照してください」とのこと。yumモジュールのコードそのものを書き換えれば動くのでしょうが将来的なことを考えれば素直にdnfを利用するのが良さそうです。
そもそもdnfに移行したい
yumはPython2で動作しており、Python2のサポートは2020年1月1日で終了すると公式にアナウンスがあったため、こちらとしてもdnfに移行したいんですけどねw
Sunsetting Python 2 We have decided that January 1, 2020, will be the day that we sunset Python 2. That means that we will not improve it anymore after that day, even if someone finds a security problem in it. You should upgrade to Python 3 as soon as you can.
※公式サイトより
AmazonLinux上のyum
実際にAmaoznLinux1でインスタンスを立ち上げて確認してみるとPython2.7で動いてますね。
$ cat /etc/os-release NAME="Amazon Linux AMI" VERSION="2018.03" $ yum --version 3.4.3 $ ls -l /usr/bin/yum -rwxr-xr-x 1 root root 804 8月 11 2017 /usr/bin/yum $ head -1 /usr/bin/yum #!/usr/bin/python2.7
標準のリポジトリにはdnfさんがいないので、別途リポジトリを追加するかrpmのパッケージをどこかから拾ってくるなど何らかの対応が必要です。
$ yum search dnf 警告: 一致するものが見つかりません: dnf No matches found
ちなみにepelを入れても見つかりません\(^o^)/
$ sudo yum -y install epel-release $ yum search dnf --enablerepo=epel 警告: 一致するものが見つかりません: dnf No matches found
ディストリビューションによってはyumがdnfのシンボリックリンクになっていたりするんですが、AmazonLinux上でも手軽にdnfが利用できる日が来ることを祈ってやみません。
参考ページ
翔泳社
売り上げランキング: 21,899