# Buggy code
def create_instance(module, client, instance_name):
    """
    Create an instance

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

    Returns a dictionary of instance information
    about the new instance.

    """

    changed = False

    # Check if instance already exists
    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)
            )

    zone = module.params.get("zone")
    blueprint_id = module.params.get("blueprint_id")
    bundle_id = module.params.get("bundle_id")
    key_pair_name = module.params.get("key_pair_name")
    user_data = module.params.get("user_data")
    user_data = "" if user_data is None else user_data

    resp = None
    if inst is None:
        try:
            resp = client.create_instances(
                instanceNames=[instance_name],
                availabilityZone=zone,
                blueprintId=blueprint_id,
                bundleId=bundle_id,
                userData=user_data,
                keyPairName=key_pair_name,
            )
            resp = resp["operations"][0]
        except botocore.exceptions.ClientError as e:
            module.fail_json(
                msg="Unable to create instance {0}, error: {1}".format(instance_name, e)
            )
        changed = True

    inst = _find_instance_info(client, instance_name)

    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 create_instance(module, client, instance_name):
    inst = find_instance_info(module, client, instance_name)
    if inst:
        module.exit_json(changed=False, instance=camel_dict_to_snake_dict(inst))
    else:
        create_params = {
            "instanceNames": [instance_name],
            "availabilityZone": module.params.get("zone"),
            "blueprintId": module.params.get("blueprint_id"),
            "bundleId": module.params.get("bundle_id"),
            "userData": module.params.get("user_data"),
        }

        key_pair_name = module.params.get("key_pair_name")
        if key_pair_name:
            create_params["keyPairName"] = key_pair_name

        try:
            client.create_instances(**create_params)
        except botocore.exceptions.ClientError as e:
            module.fail_json_aws(e)

        wait = module.params.get("wait")
        if wait:
            desired_states = ["running"]
            wait_for_instance_state(module, client, instance_name, desired_states)
        inst = find_instance_info(module, client, instance_name, fail_if_not_found=True)

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