[Ansible] yumモジュールをdnfがインストールされていない環境で使う

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を利用するのが良さそうです。

docs.ansible.com

そもそも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  811  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が利用できる日が来ることを祈ってやみません。

参考ページ

インフラCI実践ガイド Ansible/GitLabを使ったインフラ改善サイクルの実現
中島 倫明 佐々木 健太郎 北山 晋吾 齊藤 秀喜 羽深 修
翔泳社
売り上げランキング: 21,899