# Buggy code
def copy_image(module, ec2):
    """
    Copies an AMI

    module : AnsibleModule object
    ec2: ec2 connection object
    """

    tags = module.params.get("tags")

    params = {
        "SourceRegion": module.params.get("source_region"),
        "SourceImageId": module.params.get("source_image_id"),
        "Name": module.params.get("name"),
        "Description": module.params.get("description"),
        "Encrypted": module.params.get("encrypted"),
    }
    if module.params.get("kms_key_id"):
        params["KmsKeyId"] = module.params.get("kms_key_id")

    try:
        image_id = ec2.copy_image(**params)["ImageId"]
        if module.params.get("wait"):
            ec2.get_waiter("image_available").wait(ImageIds=[image_id])
        if module.params.get("tags"):
            ec2.create_tags(
                Resources=[image_id],
                Tags=[
                    {"Key": k, "Value": v} for k, v in module.params.get("tags").items()
                ],
            )

        module.exit_json(changed=True, image_id=image_id)
    except WaiterError as we:
        module.fail_json(
            msg="An error occurred waiting for the image to become available. (%s)"
            % we.reason
        )
    except ClientError as ce:
        module.fail_json(msg=ce.message)
    except NoCredentialsError:
        module.fail_json(msg="Unable to authenticate, AWS credentials are invalid.")
    except Exception as e:
        module.fail_json(msg="Unhandled exception. (%s)" % str(e))


# Traceback (AttributeError)
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: AttributeError: 'WaiterError' object has no attribute 'reason'
/aws/codebuild/core-build-ami c6b4c0b1-5035-4833-8456-f486d8f78e27 fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "module_stderr": "Traceback (most recent call last):
File \"/tmp/ansible_wM5kH0/ansible_module_ec2_ami_copy.py\", line 226, in <module>
main()
File \"/tmp/ansible_wM5kH0/ansible_module_ec2_ami_copy.py\", line 222, in main
copy_image(module, ec2)
File \"/tmp/ansible_wM5kH0/ansible_module_ec2_ami_copy.py\", line 183, in copy_image
module.fail_json(msg='An error occured waiting for the image to become available. (%s)' %  we.reason)
AttributeError: 'WaiterError' object has no attribute 'reason'
", "module_stdout": "", "msg": "MODULE FAILURE", "rc": 0}

# Fixed code
def copy_image(module, ec2):
    """
    Copies an AMI

    module : AnsibleModule object
    ec2: ec2 connection object
    """

    tags = module.params.get("tags")

    params = {
        "SourceRegion": module.params.get("source_region"),
        "SourceImageId": module.params.get("source_image_id"),
        "Name": module.params.get("name"),
        "Description": module.params.get("description"),
        "Encrypted": module.params.get("encrypted"),
    }
    if module.params.get("kms_key_id"):
        params["KmsKeyId"] = module.params.get("kms_key_id")

    try:
        image_id = ec2.copy_image(**params)["ImageId"]
        if module.params.get("wait"):
            ec2.get_waiter("image_available").wait(ImageIds=[image_id])
        if module.params.get("tags"):
            ec2.create_tags(
                Resources=[image_id],
                Tags=[
                    {"Key": k, "Value": v} for k, v in module.params.get("tags").items()
                ],
            )

        module.exit_json(changed=True, image_id=image_id)
    except WaiterError as we:
        module.fail_json(
            msg="An error occurred waiting for the image to become available. (%s)"
            % str(we),
            exception=traceback.format_exc(),
        )
    except ClientError as ce:
        module.fail_json(msg=ce.message)
    except NoCredentialsError:
        module.fail_json(msg="Unable to authenticate, AWS credentials are invalid.")
    except Exception as e:
        module.fail_json(msg="Unhandled exception. (%s)" % str(e))