pythonpython-3.xansibleansible-2.xansible-module

Custom Ansible module is giving param extra params error


I am trying to implement hostname like module and my target machine in an amazon-ec2. But When I am running the script its giving me below error:

[ansible-user@ansible-master ~]$ ansible node1 -m edit_hostname.py -a node2
ERROR! this task 'edit_hostname.py' has extra params, which is only allowed in the following modules: meta, group_by, add_host, include_tasks, import_role, raw, set_fact, command, win_shell, import_tasks, script, shell, include_vars, include_role, include, win_command

My module is like this:

#!/usr/bin/python


from ansible.module_utils.basic import *

try:
    import json
except ImportError:
    import simplejson as json


def write_to_file(module, hostname, hostname_file):

    try:
        with open(hostname_file, 'w+') as f:
            try:
                f.write("%s\n" %hostname)
            finally:
                f.close()
    except Exception:
        err = get_exception()
        module.fail_json(msg="failed to write to the /etc/hostname file")

def main():

    hostname_file = '/etc/hostname'
    module = AnsibleModule(argument_spec=dict(name=dict(required=True, type=str)))
    name = module.params['name']
    write_to _file(module, name, hostname_file)
    module.exit_json(changed=True, meta=name)

if __name__ == "__main__":

    main()

I don't know where I am making the mistake. Any help will be greatly appreciated. Thank you.


Solution

  • When developing a new module, I would recommend to use the boilerplate described in the documentation. This also shows that you'll need to use AnsibleModule to define your arguments.

    In your main, you should add something like the following:

    def main():
        # define available arguments/parameters a user can pass to the module
        module_args = dict(
            name=dict(type='str', required=True)
        )
    
        # seed the result dict in the object
        # we primarily care about changed and state
        # change is if this module effectively modified the target
        # state will include any data that you want your module to pass back
        # for consumption, for example, in a subsequent task
        result = dict(
            changed=False,
            original_hostname='',
            hostname=''
        )
    
        module = AnsibleModule(
            argument_spec=module_args
            supports_check_mode=False
        )
    
        # manipulate or modify the state as needed (this is going to be the
        # part where your module will do what it needs to do)
        result['original_hostname'] = module.params['name']
        result['hostname'] = 'goodbye'
    
        # use whatever logic you need to determine whether or not this module
        # made any modifications to your target
        result['changed'] = True
    
        # in the event of a successful module execution, you will want to
        # simple AnsibleModule.exit_json(), passing the key/value results
        module.exit_json(**result)
    

    Then, you can call the module like so:

    ansible node1 -m mymodule.py -a "name=myname"