無能が苦悩したメモ

無能な著者が学んだことを忘れないための覚え書きです...

Ansible:roles_pathでロール検索パスを設定する

*ansible 2.10.4で動作を確認しています

Ansibleでroleを利用する際、よく見かけるのは以下のようなディレクトリ構成かと思います。プレイブック(playbook.yml)と同じ階層にrolesというディレクトリが存在し、その下にロールが存在するという構成です。

|-- inventory
|-- playbook.yml
`-- roles
    `-- foo
        `-- tasks
            `-- main.yml


Ansibleは標準でロールを検索する際、プレイブックからの相対パスでrolesというディレクトリを検索するそうで、そのため、playbook.ymlからroles/fooを実行できるわけです。

rolesを他の場所に配置したい

以下のように、プレイブック(playbook.yml)とは別の階層にrolesを配置したとします。

|-- host1
|   `-- playbook.yml
|-- inventory
`-- roles
    `-- foo
        `-- tasks
            `-- main.yml


この時、playbook.ymlを実行すると検索パスにrolesが存在しないためエラーが出てしまいます。

---
- hosts: all
  roles:
    - foo


---
- name: output message
  debug:
    msg: "foo"


$ pwd
/home/muknow/workspace/ansible/test_role_path
$ ls
host1  inventory  roles
$ ansible-playbook -i inventory host1/playbook.yml
ERROR! the role 'foo' was not found in /home/muknow/workspace/ansible/test_role_path/host1/roles:/home/muknow/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:/home/muknow/workspace/ansible/test_role_path/host1

The error appears to be in '/home/muknow/workspace/ansible/test_role_path/host1/playbook.yml': line 5, column 7, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  roles:
    - foo
      ^ here


roles_pathを設定する

ansible.cfgでroles_pathを設定することで検索パスを追加することができます。検索パスを追加すれば、このプレイブックもうまく実行できるはずです。


今回はansible.cfgをrolesと同じ階層に配置し、ここからansible-playbookコマンドを実行することにします。roles_pathには相対パスでrolesを指定しました。

[defaults]
roles_path    = ./roles


最終的な構成は以下のようになります。

|-- ansible.cfg
|-- host1
|   `-- playbook.yml
|-- inventory
`-- roles
    `-- foo
        `-- tasks
            `-- main.yml


fooが実行されました。成功です。

$ pwd
/home/muknow/workspace/ansible/test_role_path
$ ls
ansible.cfg  host1  inventory  roles
$ ansible-playbook -i inventory host1/playbook.yml

PLAY [all] **************************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [CentOS7.6]

TASK [foo : output message] *********************************************************************************************************************************
ok: [CentOS7.6] => {
    "msg": "foo"
}

PLAY RECAP **************************************************************************************************************************************************
CentOS7.6                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0


host1の下にもrolesを作ったらどうなるのか?

気になったのでためしてみました。


先ほどの構成から追加で、host1の下にrolesを作り、barとfooというロールを作成しました。fooに関しては、同じ名前のロールがrolesの下、host1/rolesの下の2か所に存在する場合、どちらが優先されるかを見てみたいと思います。

|-- ansible.cfg
|-- host1
|   |-- playbook.yml
|   `-- roles
|       |-- bar
|       |   `-- tasks
|       |       `-- main.yml
|       `-- foo
|           `-- tasks
|               `-- main.yml
|-- inventory
`-- roles
    `-- foo
        `-- tasks
            `-- main.yml


---
- hosts: all
  roles:
    - bar
    - foo


---
- name: output message
  debug:
    msg: "bar [host1/roles/bar]"


---
- name: output message
  debug:
    msg: "foo [host1/roles/foo]"


---
- name: output message
  debug:
    msg: "foo [roles/foo]"



実行結果は以下となりました。
fooはroles/fooとhost1/roles/fooの2か所に作成しましたが、host1/roles/fooが実行されています。どうやら、roles_pathの設定したパスよりも、プレイブックと同階層のrolesの方が優先されるようです。

$ pwd
/home/muknow/workspace/ansible/test_role_path
$ ls
ansible.cfg  host1  inventory  roles
$ ansible-playbook -i inventory host1/playbook.yml

PLAY [all] **************************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [CentOS7.6]

TASK [bar : output message] *********************************************************************************************************************************
ok: [CentOS7.6] => {
    "msg": "bar [host1/roles/bar]"
}

TASK [foo : output message] *********************************************************************************************************************************
ok: [CentOS7.6] => {
    "msg": "foo [host1/roles/foo]"
}

PLAY RECAP **************************************************************************************************************************************************
CentOS7.6                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0