# Buggy code
def restart_instance(module, client, instance_name):
    """
    Reboot an existing instance

    module: Ansible module object
    client: authenticated lightsail connection object
    instance_name: name of instance to reboot

    Returns a dictionary of instance information
    about the restarted instance

    If the instance was not able to reboot,
    "changed" will be set to False.

    Wait will not apply here as this is an OS-level operation
    """
    wait = module.params.get("wait")
    wait_timeout = int(module.params.get("wait_timeout"))
    wait_max = time.time() + wait_timeout

    changed = False

    inst = None
    try:
        inst = _find_instance_info(client, instance_name)
    except botocore.exceptions.ClientError as e:
        if e.response["Error"]["Code"] != "NotFoundException":
            module.fail_json(
                msg="Error finding instance {0}, error: {1}".format(instance_name, e)
            )

    # Wait for instance to exit transition state before state change
    if wait:
        while (
            wait_max > time.time()
            and inst is not None
            and inst["state"]["name"] in ("pending", "stopping")
        ):
            try:
                time.sleep(5)
                inst = _find_instance_info(client, instance_name)
            except botocore.exceptions.ClientError as e:
                if e.response["ResponseMetadata"]["HTTPStatusCode"] == "403":
                    module.fail_json(
                        msg="Failed to restart instance {0}. Check that you have permissions to perform the operation.".format(
                            instance_name
                        ),
                        exception=traceback.format_exc(),
                    )
                elif e.response["Error"]["Code"] == "RequestExpired":
                    module.fail_json(
                        msg="RequestExpired: Failed to restart instance {0}.".format(
                            instance_name
                        ),
                        exception=traceback.format_exc(),
                    )
                time.sleep(3)

    # send reboot
    if inst is not None:
        try:
            client.reboot_instance(instanceName=instance_name)
        except botocore.exceptions.ClientError as e:
            if e.response["Error"]["Code"] != "NotFoundException":
                module.fail_json(
                    msg="Unable to reboot instance {0}, error: {1}".format(
                        instance_name, e
                    )
                )
        changed = True

    return (changed, inst)


# Traceback (ParamValidationError)
The full traceback is:
Traceback (most recent call last):
File "/tmp/ansible_Vslj3B/ansible_module_lightsail.py", line 467, in main
core(module)
File "/tmp/ansible_Vslj3B/ansible_module_lightsail.py", line 429, in core
changed, instance_dict = create_instance(module, client, name)
File "/tmp/ansible_Vslj3B/ansible_module_lightsail.py", line 219, in create_instance
keyPairName=key_pair_name,
File "/home/jack/git/lightsail/ansible/env/local/lib/python2.7/site-packages/botocore/client.py", line 324, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/home/jack/git/lightsail/ansible/env/local/lib/python2.7/site-packages/botocore/client.py", line 596, in _make_api_call
api_params, operation_model, context=request_context)
File "/home/jack/git/lightsail/ansible/env/local/lib/python2.7/site-packages/botocore/client.py", line 631, in _convert_to_request_dict
api_params, operation_model)
File "/home/jack/git/lightsail/ansible/env/local/lib/python2.7/site-packages/botocore/validate.py", line 291, in serialize_to_request
raise ParamValidationError(report=report.generate_report())
ParamValidationError: Parameter validation failed:
Invalid type for parameter keyPairName, value: None, type: <type 'NoneType'>, valid types: <type 'basestring'>

fatal: [localhost]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"aws_access_key": null,
"aws_secret_key": null,
"blueprint_id": "ubuntu_16_04",
"bundle_id": "nano_1_0",
"ec2_url": null,
"key_pair_name": null,
"name": "test",
"profile": null,
"region": "eu-west-1",
"security_token": null,
"state": "present",
"user_data": null,
"validate_certs": true,
"wait": true,
"wait_timeout": "500",
"zone": "eu-west-1a"
}
},
"msg": "Parameter validation failed:\nInvalid type for parameter keyPairName, value: None, type: <type 'NoneType'>, valid types: <type 'basestring'>"
}

# Fixed code
def restart_instance(module, client, instance_name):
    """
    Reboot an existing instance
    Wait will not apply here as this is an OS-level operation
    """

    changed = False

    inst = find_instance_info(module, client, instance_name, fail_if_not_found=True)

    try:
        client.reboot_instance(instanceName=instance_name)
        changed = True
    except botocore.exceptions.ClientError as e:
        module.fail_json_aws(e)

    module.exit_json(changed=changed, instance=camel_dict_to_snake_dict(inst))