# Buggy code
def ensure_subnet_present(conn, module):
    subnet = get_matching_subnet(
        conn, module, module.params["vpc_id"], module.params["cidr"]
    )
    changed = False

    # Initialize start so max time does not exceed the specified wait_timeout for multiple operations
    start_time = time.time()

    if subnet is None:
        if not module.check_mode:
            subnet = create_subnet(
                conn,
                module,
                module.params["vpc_id"],
                module.params["cidr"],
                ipv6_cidr=module.params["ipv6_cidr"],
                az=module.params["az"],
                start_time=start_time,
            )
        changed = True
        # Subnet will be None when check_mode is true
        if subnet is None:
            return {"changed": changed, "subnet": {}}
    if module.params["wait"]:
        handle_waiter(
            conn, module, "subnet_exists", {"SubnetIds": [subnet["id"]]}, start_time
        )

    if module.params["ipv6_cidr"] != subnet.get("ipv6_cidr_block"):
        if ensure_ipv6_cidr_block(
            conn,
            module,
            subnet,
            module.params["ipv6_cidr"],
            module.check_mode,
            start_time,
        ):
            changed = True

    if module.params["map_public"] != subnet["map_public_ip_on_launch"]:
        ensure_map_public(
            conn,
            module,
            subnet,
            module.params["map_public"],
            module.check_mode,
            start_time,
        )
        changed = True

    if module.params["assign_instances_ipv6"] != subnet.get(
        "assign_ipv6_address_on_creation"
    ):
        ensure_assign_ipv6_on_create(
            conn,
            module,
            subnet,
            module.params["assign_instances_ipv6"],
            module.check_mode,
            start_time,
        )
        changed = True

    if module.params["tags"] != subnet["tags"]:
        stringified_tags_dict = dict(
            (to_text(k), to_text(v)) for k, v in module.params["tags"].items()
        )
        if ensure_tags(
            conn,
            module,
            subnet,
            stringified_tags_dict,
            module.params["purge_tags"],
            start_time,
        ):
            changed = True

    subnet = get_matching_subnet(
        conn, module, module.params["vpc_id"], module.params["cidr"]
    )

    return {"changed": changed, "subnet": subnet}


# Traceback (ClientError)
Traceback (most recent call last):
File "/tmp/ansible_dPE6PL/ansible_module_ec2_vpc_net.py", line 203, in get_vpc
classic_link = connection.describe_vpc_classic_link(VpcIds=[vpc_id])['Vpcs'][0].get('ClassicLinkEnabled')
File "/usr/local/lib/python2.7/dist-packages/botocore/client.py", line 317, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/usr/local/lib/python2.7/dist-packages/botocore/client.py", line 615, in _make_api_call
raise error_class(parsed_response, operation_name)
ClientError: An error occurred (InvalidVpcID.NotFound) when calling the DescribeVpcClassicLink operation: The vpc ID 'vpc-1b2bda60' does not exist

# Fixed code
def ensure_subnet_present(conn, module):
    subnet = get_matching_subnet(
        conn, module, module.params["vpc_id"], module.params["cidr"]
    )
    changed = False

    # Initialize start so max time does not exceed the specified wait_timeout for multiple operations
    start_time = time.time()

    if subnet is None:
        if not module.check_mode:
            subnet = create_subnet(
                conn,
                module,
                module.params["vpc_id"],
                module.params["cidr"],
                ipv6_cidr=module.params["ipv6_cidr"],
                az=module.params["az"],
                start_time=start_time,
            )
        changed = True
        # Subnet will be None when check_mode is true
        if subnet is None:
            return {"changed": changed, "subnet": {}}
    if module.params["wait"]:
        handle_waiter(
            conn, module, "subnet_exists", {"SubnetIds": [subnet["id"]]}, start_time
        )

    if module.params["ipv6_cidr"] != subnet.get("ipv6_cidr_block"):
        if ensure_ipv6_cidr_block(
            conn,
            module,
            subnet,
            module.params["ipv6_cidr"],
            module.check_mode,
            start_time,
        ):
            changed = True

    if module.params["map_public"] != subnet["map_public_ip_on_launch"]:
        ensure_map_public(
            conn,
            module,
            subnet,
            module.params["map_public"],
            module.check_mode,
            start_time,
        )
        changed = True

    if module.params["assign_instances_ipv6"] != subnet.get(
        "assign_ipv6_address_on_creation"
    ):
        ensure_assign_ipv6_on_create(
            conn,
            module,
            subnet,
            module.params["assign_instances_ipv6"],
            module.check_mode,
            start_time,
        )
        changed = True

    if module.params["tags"] != subnet["tags"]:
        stringified_tags_dict = dict(
            (to_text(k), to_text(v)) for k, v in module.params["tags"].items()
        )
        if ensure_tags(
            conn,
            module,
            subnet,
            stringified_tags_dict,
            module.params["purge_tags"],
            start_time,
        ):
            changed = True

    subnet = get_matching_subnet(
        conn, module, module.params["vpc_id"], module.params["cidr"]
    )
    if not module.check_mode and module.params["wait"]:
        # GET calls are not monotonic for map_public_ip_on_launch and assign_ipv6_address_on_creation
        # so we only wait for those if necessary just before returning the subnet
        subnet = ensure_final_subnet(conn, module, subnet, start_time)

    return {"changed": changed, "subnet": subnet}