Ansible 自作モジュールが認識されなかった


Ansibleの自作モジュール作ろうとすると素敵な参考サイトがたくさん見つかります。

が、見て学んだとおりに自作モジュールを配置しても認識されない事象にぶつかりました。

$ ansible -i develop 192.168.56.103 -m plain -u root
192.168.56.103 | FAILED! => {
    "msg": "The module plain was not found in configured module paths"
}

果たしていったいどうすればよかったのか、の記録です。

環境

$ cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)

$ ansible --version
ansible 2.9.7
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/ansi/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /bin/ansible
  python version = 2.7.5 (default, Aug  7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]

リポジトリ構成

Best Practicesに沿って作ったつもり

/home/ansi/repo/
    site.yml
    icanfly.yml
    develop/
        hosts
    group_vars/
        all.yml
        develop/
            main.yml
    library/
        plain.sh       # ココに置いた
    role/
        common/
            tasks/
                main.yml
        file/
        template/
site.yml
---
- import_playbook: icanfly.yml
icanfly.yml
---
- hosts: test_grp
  roles:
    - common
plain.sh
#!/bin/bash
echo '{}'

-m ping を思い出す

初めてモジュールを作った時に、いきなりplay-bookに組み込むんじゃなくて単体で試そうと考えました。
例えばよくある -m ping みたいな。

$ cd /home/ansi/repo
$ ansible -i develop 192.168.56.103 -m ping -u root
192.168.56.103 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

とした時に「Ansible Best Practices library」と検索するとだいたいは

Ansible のモジュールは
- ansible.cfg の library で指定されたディレクトリ
- 環境変数 ANSIBLE_LIBRARY で指定されたディレクトリ
- コマンドラインで –-module-path で指定されたディレクトリ
- 実行ディレクトリ直下にある library という名前のディレクトリ
から検索されます。

て書かれているんですよ。
これを鵜呑みにして実行したのが以下。

$ ansible -i develop 192.168.56.103 -m plain -u root
192.168.56.103 | FAILED! => {
    "msg": "The module plain was not found in configured module paths"
}

モジュール見つかりません、という話ですね。

モジュール場所を指定してみる

library/plain.shがそもそもモジュールの体を成していないのかなと思って先に記載したモジュールを認識される条件の「コマンドラインで --module-path で指定されたディレクトリ」を試します。

$ ansible -i develop 192.168.56.103 -m plain -u root --module-path library
192.168.56.103 | SUCCESS => {
    "changed": false
}

あれ、できちゃった。ということはやはり「library配下に置いたけど認識してくれない」ということですね。

結論

なんかもう色々試してたんですが解決に至ったのは以下のサイトでした。

Ansible モジュール作成のイロハ

というか先程の引用のサイトなんですけど、後ろにもう少し文章が続くんですね。

Ansible のモジュールは
- ansible.cfg の library で指定されたディレクトリ
- 環境変数 ANSIBLE_LIBRARY で指定されたディレクトリ
- コマンドラインで –-module-path で指定されたディレクトリ
- 実行ディレクトリ直下にある library という名前のディレクトリ
から検索されます。プロジェクト固有のものは playbook を実行するディレクトリの直下に library を作るという最後の方法がバージョン管理的にも実行のしやすさからいっても便利でしょう。

「playbook を実行するディレクトリの直下に」と書いてあるんです。
そうです、いま試していたコマンドは playbook を実行していないんです。

$ mkdir -p roles/test/tasks
$ cat <<EOF >> roles/test/tasks/main.yml
- name: test plain
  plain:
EOF

$ cat <<EOF >> test.yml
---
- hosts: test_grp
  roles:
    - test
EOF

$ ansible-playbook -i develop -l test_grp -u root test.yml

PLAY [logget_tool] ***********************************************************************************************

TASK [Gathering Facts] *******************************************************************************************
ok: [192.168.56.103]

TASK [test : test plain] *****************************************************************************************
ok: [192.168.56.103]

PLAY RECAP *******************************************************************************************************
192.168.56.103             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

で!き!た!!

playbookの場合ならlibrary配下を検索してくれるんですね。
あーすっきりした。。