最近Ansibleの資格試験を準備していて、Ansible Automation Platform(以下AAPとする)には、レポジトリにある.py
のDynamic Inventoryはなかなか表示されないことがありました。この記事ではDynamic Inventory Fileを表示させた方法を書きます。
環境定義と問題再現 (解決方法は一番最後に)
まずはテストするために、以下のファイルを定義しました。
環境定義
inventory
[lb]
servera.lab.example.com
[web]
serverb.lab.example.com
serverc.lab.example.com
ansible.cfg
[defaults]
inventory=inventory
hello_world.yml
- name: Hello World Sample
hosts: all
gather_facts: no
tasks:
- name: Hello Message
debug:
msg: "Hello World!"
dynamic_inventory.py
#! のパスは各自Python3に指定する必要があると思います
#!/bin python3
import json
def get_inventory():
inventory = {
'lb': {
'hosts': ['servera.lab.example.com']
},
'web': {
'hosts': ['serverb.lab.example.com', 'serverc.lab.example.com']
},
'_meta': {
'hostvars': {}
}
}
return inventory
def main():
import sys
if len(sys.argv) == 2 and (sys.argv[1] == '--list' or sys.argv[1] == '--host'):
if sys.argv[1] == '--list':
print(json.dumps(get_inventory()))
elif sys.argv[1] == '--host':
print(json.dumps({}))
else:
print("Usage: %s --list | --host <hostname>" % sys.argv[0])
sys.exit(1)
if __name__ == '__main__':
main()
一部コマンドの実行結果
tree and ll
# tree
.
├── ansible.cfg
├── dynamic_inventory.py
├── hello_world.yml
└── inventory
# ll
total 16
-rw-rw-r--. 1 student student 31 May 26 02:39 ansible.cfg
-rw-rw-r--. 1 student student 735 May 26 02:49 dynamic_inventory.py
-rw-rw-r--. 1 student student 135 May 26 02:39 hello_world.yml
-rw-rw-r--. 1 student student 85 May 26 02:43 inventory
# ansible-playbook hello_world.yml
PLAY [Hello World Sample] *************************************************************
TASK [Hello Message] ******************************************************************
ok: [servera.lab.example.com] => {
"msg": "Hello World!"
}
ok: [serverb.lab.example.com] => {
"msg": "Hello World!"
}
ok: [serverc.lab.example.com] => {
"msg": "Hello World!"
}
PLAY RECAP ****************************************************************************
servera.lab.example.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverb.lab.example.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverc.lab.example.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
# ansible-playbook -i dynamic_inventory.py hello_world.yml
[WARNING]: * Failed to parse /home/student/git-repos/advanced-inventory/dynamic_inventory.py with script plugin: problem running
/home/student/git-repos/advanced-inventory/dynamic_inventory.py --list ([Errno 13] Permission denied: '/home/student/git-repos/advanced-inventory/dynamic_inventory.py')
[WARNING]: * Failed to parse /home/student/git-repos/advanced-inventory/dynamic_inventory.py with ini plugin: /home/student/git-
repos/advanced-inventory/dynamic_inventory.py:2: Expected key=value host variable assignment, got: json
[WARNING]: Unable to parse /home/student/git-repos/advanced-inventory/dynamic_inventory.py as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [Hello World Sample] *************************************************************
skipping: no hosts matched
PLAY RECAP ****************************************************************************
ansible-playbook hello_world.yml
$ ansible-playbook hello_world.yml
PLAY [Hello World Sample] *************************************************************
TASK [Hello Message] ******************************************************************
ok: [servera.lab.example.com] => {
"msg": "Hello World!"
}
ok: [serverb.lab.example.com] => {
"msg": "Hello World!"
}
ok: [serverc.lab.example.com] => {
"msg": "Hello World!"
}
PLAY RECAP ****************************************************************************
servera.lab.example.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverb.lab.example.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverc.lab.example.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
# ansible-playbook -i dynamic_inventory.py hello_world.yml
[WARNING]: * Failed to parse /home/student/git-repos/advanced-inventory/dynamic_inventory.py with script plugin: problem running
/home/student/git-repos/advanced-inventory/dynamic_inventory.py --list ([Errno 13] Permission denied: '/home/student/git-repos/advanced-inventory/dynamic_inventory.py')
[WARNING]: * Failed to parse /home/student/git-repos/advanced-inventory/dynamic_inventory.py with ini plugin: /home/student/git-
repos/advanced-inventory/dynamic_inventory.py:2: Expected key=value host variable assignment, got: json
[WARNING]: Unable to parse /home/student/git-repos/advanced-inventory/dynamic_inventory.py as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [Hello World Sample] *************************************************************
skipping: no hosts matched
PLAY RECAP ****************************************************************************
ansible-playbook -i dynamic_inventory.py hello_world.yml
$ ansible-playbook -i dynamic_inventory.py hello_world.yml
[WARNING]: * Failed to parse /home/student/git-repos/advanced-inventory/dynamic_inventory.py with script plugin: problem running
/home/student/git-repos/advanced-inventory/dynamic_inventory.py --list ([Errno 13] Permission denied: '/home/student/git-repos/advanced-inventory/dynamic_inventory.py')
[WARNING]: * Failed to parse /home/student/git-repos/advanced-inventory/dynamic_inventory.py with ini plugin: /home/student/git-
repos/advanced-inventory/dynamic_inventory.py:2: Expected key=value host variable assignment, got: json
[WARNING]: Unable to parse /home/student/git-repos/advanced-inventory/dynamic_inventory.py as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [Hello World Sample] *************************************************************
skipping: no hosts matched
PLAY RECAP ****************************************************************************
再現
この状態でAAPにおいて、Inventoryを作成して、SourceをSourced from a Project
に指定しても、Inventory file
には作成していたdynamic_inventory.py
は表示されることがなく、inventory
しかなかったです。
もちろん手動で入力してもエラーになりました。
解決方法
dynamic inventoryは実行可能なファイルでないといけないことが分かり、以下のコマンドを実行すれば無事に反映されました。
chmod +x dynamic_inventory.py
# ProjectにPushして、AAP ProjectでSyncを行います。
git add dynamic_inventory.py
git commit -m "add x to dynamic inventory"
git push
最後に
Ansible Dynamic Inventoryの知識は以前から頭に入っていましたが、実践経験が少なかったため、実際の問題に出会った際、Ansible Documentを調べていても、操作していてもpyファイルを認識されていなく、慌てていました。実際一度手で触って見れば、二度と忘れることのない解決方法でした。やはり、知識の吸収よりは、実践経験を積むのですね。