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

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

- [Ansibleのモジュール開発（基礎編）](https://dev.classmethod.jp/articles/ansible-develop-module-basis/)
- [自作モジュール](https://machiiro.github.io/bootcamp/ansible/base/07_custom_module.html)

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

```bash
$ 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"
}
```

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

# 環境

```bash
$ 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](https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html)に沿って作ったつもり

```
/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/
```

```yml:site.yml
---
- import_playbook: icanfly.yml
```

```yml:icanfly.yml
---
- hosts: test_grp
  roles:
    - common
```

```bash:plain.sh
#!/bin/bash
echo '{}'
```

# ``-m ping`` を思い出す

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

```bash
$ 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 という名前のディレクトリ
から検索されます。

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


```bash
$ 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`` で指定されたディレクトリ」を試します。

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

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

# 結論

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

[Ansible モジュール作成のイロハ](https://nulab.com/ja/blog/backlog/ansible-module-1/)

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


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

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

```bash
$ 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``配下を検索してくれるんですね。
あーすっきりした。。