# Buggy code
def main():
    argument_spec = dict(
        name=dict(required=True),
        description=dict(required=False),
        extra_vars=dict(required=False),
        organization=dict(required=False),
        allow_simultaneous=dict(type="bool", required=False),
        schema=dict(required=False),
        survey=dict(required=False),
        survey_enabled=dict(type="bool", required=False),
        inventory=dict(required=False),
        ask_inventory=dict(type="bool", required=False),
        ask_extra_vars=dict(type="bool", required=False),
        state=dict(choices=["present", "absent"], default="present"),
    )

    module = TowerModule(argument_spec=argument_spec, supports_check_mode=False)

    name = module.params.get("name")
    state = module.params.get("state")

    schema = None
    if module.params.get("schema"):
        schema = module.params.get("schema")

    if schema and state == "absent":
        module.fail_json(
            msg="Setting schema when state is absent is not allowed", changed=False
        )

    json_output = {"workflow_template": name, "state": state}

    tower_auth = tower_auth_config(module)
    with settings.runtime_values(**tower_auth):
        tower_check_mode(module)
        wfjt_res = tower_cli.get_resource("workflow")
        params = {}
        params["name"] = name

        if module.params.get("description"):
            params["description"] = module.params.get("description")

        if module.params.get("organization"):
            organization_res = tower_cli.get_resource("organization")
            try:
                organization = organization_res.get(
                    name=module.params.get("organization")
                )
                params["organization"] = organization["id"]
            except exc.NotFound as excinfo:
                module.fail_json(
                    msg="Failed to update organization source,"
                    "organization not found: {0}".format(excinfo),
                    changed=False,
                )

        if module.params.get("survey"):
            params["survey_spec"] = module.params.get("survey")

        if module.params.get("ask_extra_vars"):
            params["ask_variables_on_launch"] = module.params.get("ask_extra_vars")

        if module.params.get("ask_inventory"):
            params["ask_inventory_on_launch"] = module.params.get("ask_inventory")

        for key in (
            "allow_simultaneous",
            "extra_vars",
            "inventory",
            "survey_enabled",
            "description",
        ):
            if module.params.get(key):
                params[key] = module.params.get(key)

        try:
            if state == "present":
                params["create_on_missing"] = True
                result = wfjt_res.modify(**params)
                json_output["id"] = result["id"]
                if schema:
                    wfjt_res.schema(result["id"], schema)
            elif state == "absent":
                params["fail_on_missing"] = False
                result = wfjt_res.delete(**params)
        except (exc.ConnectionError, exc.BadRequest, exc.AuthError) as excinfo:
            module.fail_json(
                msg="Failed to update workflow template: \
                    {0}".format(excinfo),
                changed=False,
            )

    json_output["changed"] = result["changed"]
    module.exit_json(**json_output)


# Traceback (tower_cli.exceptions.TowerCLIError)
The full traceback is:
Traceback (most recent call last):
File "<stdin>", line 102, in <module>
File "<stdin>", line 94, in _ansiballz_main
File "<stdin>", line 40, in invoke_module
File "/usr/lib64/python2.7/runpy.py", line 176, in run_module
fname, loader, pkg_name)
File "/usr/lib64/python2.7/runpy.py", line 82, in _run_module_code
mod_name, mod_fname, mod_loader, pkg_name)
File "/usr/lib64/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "/tmp/ansible_tower_workflow_template_payload_sphiyR/ansible_tower_workflow_template_payload.zip/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py", line 203, in <module>
File "/tmp/ansible_tower_workflow_template_payload_sphiyR/ansible_tower_workflow_template_payload.zip/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py", line 187, in main
File "/usr/lib/python2.7/site-packages/tower_cli/models/base.py", line 720, in modify
return self.write(pk, create_on_missing=create_on_missing, force_on_exists=True, **kwargs)
File "/usr/lib/python2.7/site-packages/tower_cli/models/base.py", line 1187, in write
kwargs['extra_vars'] = parser.process_extra_vars(kwargs['extra_vars'])
File "/usr/lib/python2.7/site-packages/tower_cli/utils/parser.py", line 130, in process_extra_vars
opt_dict = string_to_dict(extra_vars_opt, allow_kv=True)
File "/usr/lib/python2.7/site-packages/tower_cli/utils/parser.py", line 105, in string_to_dict
'variables.\nvariables: \n%s' % var_string
tower_cli.exceptions.TowerCLIError: failed to parse some of the extra variables.
variables:
{

# Fixed code
def main():
    argument_spec = dict(
        name=dict(required=True),
        description=dict(required=False),
        extra_vars=dict(type="dict", required=False),
        organization=dict(required=False),
        allow_simultaneous=dict(type="bool", required=False),
        schema=dict(type="list", elements="dict", required=False),
        survey=dict(required=False),
        survey_enabled=dict(type="bool", required=False),
        inventory=dict(required=False),
        ask_inventory=dict(type="bool", required=False),
        ask_extra_vars=dict(type="bool", required=False),
        state=dict(choices=["present", "absent"], default="present"),
    )

    module = TowerModule(argument_spec=argument_spec, supports_check_mode=False)

    name = module.params.get("name")
    state = module.params.get("state")

    schema = None
    if module.params.get("schema"):
        schema = module.params.get("schema")

    if schema and state == "absent":
        module.fail_json(
            msg="Setting schema when state is absent is not allowed", changed=False
        )

    json_output = {"workflow_template": name, "state": state}

    tower_auth = tower_auth_config(module)
    with settings.runtime_values(**tower_auth):
        tower_check_mode(module)
        wfjt_res = tower_cli.get_resource("workflow")
        params = {}
        params["name"] = name

        if module.params.get("description"):
            params["description"] = module.params.get("description")

        if module.params.get("organization"):
            organization_res = tower_cli.get_resource("organization")
            try:
                organization = organization_res.get(
                    name=module.params.get("organization")
                )
                params["organization"] = organization["id"]
            except exc.NotFound as excinfo:
                module.fail_json(
                    msg="Failed to update organization source,"
                    "organization not found: {0}".format(excinfo),
                    changed=False,
                )

        if module.params.get("survey"):
            params["survey_spec"] = module.params.get("survey")

        if module.params.get("ask_extra_vars"):
            params["ask_variables_on_launch"] = module.params.get("ask_extra_vars")

        if module.params.get("ask_inventory"):
            params["ask_inventory_on_launch"] = module.params.get("ask_inventory")

        for key in ("allow_simultaneous", "inventory", "survey_enabled", "description"):
            if module.params.get(key):
                params[key] = module.params.get(key)

        # Special treatment for tower-cli extra_vars
        extra_vars = module.params.get("extra_vars")
        if extra_vars:
            params["extra_vars"] = [json.dumps(extra_vars)]

        try:
            if state == "present":
                params["create_on_missing"] = True
                result = wfjt_res.modify(**params)
                json_output["id"] = result["id"]
                if schema:
                    wfjt_res.schema(result["id"], json.dumps(schema))
            elif state == "absent":
                params["fail_on_missing"] = False
                result = wfjt_res.delete(**params)
        except (exc.ConnectionError, exc.BadRequest, exc.AuthError) as excinfo:
            module.fail_json(
                msg="Failed to update workflow template: \
                    {0}".format(excinfo),
                changed=False,
            )

    json_output["changed"] = result["changed"]
    module.exit_json(**json_output)