Running Code on (Local) Ansible Controller

Hi Everyone,

I’ve just started with writing Ansible modules but am having trouble figuring out the best way to have a module run directly on the Ansible controller itself. My primary development needs are to run commands against network appliances for which I can’t copy code to (similar to the existing Cisco IOS/ASA modules).

I worked through the tutorial and the dummy module works fine
https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_general.html

When I try and add my own code to this, for some reason it switches from using the local provider to network_cli. Other than specifying to import AnsibleModule, I’ve not asked to load any other modules…perhaps the “smart” method is doing something not-so clever.

The code for my module can be found here, mainly boilerplate at the moment based of the dummy module:
https://pastebin.com/SjZ5Nfa2

In the playbook I’ve tried specifying ‘connection: local’ both at the playbook and task level which hasn’t helped. Also in the inventory file I’ve tried using ‘ansible_connection: local’ which also doesn’t seem to work for me.

The below documentation says that I should be able to do this as well as specify on the CLI:
http://docs.ansible.com/ansible/latest/playbooks_delegation.html#local-playbooks

Stack Overflow has similar comments:
https://stackoverflow.com/questions/18900236/run-command-on-the-ansible-host/18907395#18907395

My playbook is really simple:

Sorry forgot to include version info:
ansible-playbook 2.5.0 (devel 0b6c231ac1) last updated 2018/01/07 12:05:45 (GMT +100)

So I’ve played around a bit more with this, rebuilt my dev environment and still having the issue.

What I’ve discovered though is that it is the name of the module that seems to cause the problem.

I completely removed my module and just worked with the one from the tutorial and I’ve found that if I rename the test module from ‘my_new_test_module.py’ to ‘asa_my_new_test_module.py’ and now even the dummy module tries to use ‘network_cli’

Playbook used:

  • name: test my new module
    connection: local
    hosts: localhost
    gather_facts: no
    tasks:

  • name: run the new module
    my_new_test_module:
    name: ‘blah’
    new: true
    register: testout

  • name: dump test output
    debug:
    msg: ‘{{ testout }}’

$ ansible-playbook my_new_test_module.yml -vvvvv
PLAYBOOK: my_new_test_module.yml *************************************************
1 plays in my_new_test_module.yml

PLAY [test my new module] ********************************************************
META: ran handlers

TASK [run the new module] ********************************************************
task path: /home//tests/dummy_playbook/my_new_test_module.yml:7
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER:

Rename the module to ‘asa_my_new_test_module.py’ and amend playbook:

  • name: run the new module
    asa_my_new_test_module:
    name: ‘blah’
    new: true
    register: testout

$ ansible-playbook my_new_test_module.yml -vvvvv
PLAYBOOK: my_new_test_module.yml *************************************************
1 plays in my_new_test_module.yml

PLAY [test my new module] ********************************************************
META: ran handlers

TASK [run the new module] ********************************************************
task path: /home//tests/dummy_playbook/my_new_test_module.yml:7
<127.0.0.1> using connection plugin network_cli
<127.0.0.1> starting connection from persistent connection plugin
<127.0.0.1> local domain socket does not exist, starting it

It only seems to matter if the ‘asa’ bit is at the beginning, for instance ‘my_new_asa_test_module.py’ works fine.

Am I understanding it correctly that the prefix of the module in some way determines which provider to use?

Same happens if I prefix with ios, nxos but not with panos so it doesn’t constant issue.

Hope all I’ve said above makes sense.

Would really appreciate if someone could explain why this is happening.

Thanks again

Charles

This behavior is defined by the following bit of code: https://github.com/ansible/ansible/blob/3d0da8f0933fd7a7b233d28eb408a618c66eba70/lib/ansible/executor/task_executor.py#L777

If the module name prefix matches one of the prefixes for the network modules from the config, it utilizes a different action plugin:

https://github.com/ansible/ansible/blob/3d0da8f0933fd7a7b233d28eb408a618c66eba70/lib/ansible/config/base.yml#L1314

Thanks Mark,

After posting I’d started looking into actions but wasn’t able to find the right area of code, thanks for the links.

Still a lot to learn.

Charles