I'm bashing my head in at this point and could use...
# aws
a
I'm bashing my head in at this point and could use some help. I might have found a bug in subnet ID's reported availability zone? Context: • Python Pulumi project • Creates VPC + EKS using Crosswalk • Creates Managed Node Groups w/ Launch Templates The motivation here is to set capacity reservations in the launch template. Capacity reservations are specific to an availability zone. When I set the subnet as part of the managed node group, I need to know that I'm using the assigned availability zone. Issues: • At first, I thought my issue was incorrect use of Outputs. • After adding a lot of logging, I see the correct subnets being iterated through, but they all report the same availability zone even though AWS console gives me different data I'm going to dump some code and output into a thread. Should I create a ticket on github?
Here's my "pseudocode" that doesn't use Outputs properly. I want to do something sorta like this:
Copy code
def get_subnets_for_az(vpc: awsx.ec2.Vpc, target_availability_zone):
    """
    Get appropriate subnet(s) for a node group based on its configuration.

    Args:
        node_config: Node group configuration dictionary
        vpc: The VPC instance from awsx.ec2.Vpc
    """
    For non-capacity reservation nodes, use all private subnets
    if "capacity_reservation_id" not in node_config:
        return vpc.private_subnet_ids

    matching = []

    for subnet in vpc.subnets:
        if subnet.id in vpc.private_subnet_ids and subnet.availability_zone == target_availability_zone:
            matching.append(subnet.id)

    if not matching:
        pulumi.log.warn(f"No matching subnets found in AZ {target_az}")

    return matching
What I have now is this monstrosity with a bunch of logging. This was partly made with some help with both Claude + ChatGPT.
Copy code
def get_subnets_for_az(vpc: awsx.ec2.Vpc, node_config):
    """
    Get appropriate subnet(s) for a node group based on its configuration.

    Args:
        node_config: Node group configuration dictionary
        vpc: The VPC instance from awsx.ec2.Vpc
    """
    # For non-capacity reservation nodes, use all private subnets
    if "capacity_reservation_id" not in node_config:
        return vpc.private_subnet_ids

    # Capacity reservation nodes require a specific availability zone
    target_az = node_config["availability_zone"]

    # Gather all subnets and private subnet IDs using Output.all
    return pulumi.Output.all(vpc.subnets, vpc.private_subnet_ids).apply(
        lambda args: _filter_and_log_subnets(args[0], args[1], target_az)
    )


def _filter_and_log_subnets(subnets, private_ids, target_az):
    """
    Filter subnets based on availability zone and whether they're private.

    Args:
        subnets: List of subnets
        private_ids: List of private subnet IDs
        target_az: Target availability zone

    Returns:
        List of matching subnet IDs (plain list of strings, not Output objects)
    """
    <http://pulumi.log.info|pulumi.log.info>("Starting subnet filtering process.")
    <http://pulumi.log.info|pulumi.log.info>(f"Total subnets provided: {len(subnets)}")
    <http://pulumi.log.info|pulumi.log.info>(f"Private Subnet IDs provided: {private_ids}")
    <http://pulumi.log.info|pulumi.log.info>(f"Target availability zone: {target_az}")

    matching_subnets_output = []

    # Loop through each subnet and evaluate properties
    for subnet in subnets:
        def evaluate_subnet(subnet_id, subnet_az):
            subnet_az_cleaned = subnet_az.strip().lower()
            target_az_cleaned = target_az.strip().lower()

            <http://pulumi.log.info|pulumi.log.info>(f"Evaluating subnet: ID={subnet_id}, AZ={subnet_az_cleaned}")
            <http://pulumi.log.info|pulumi.log.info>(f"Comparing with Target AZ={target_az_cleaned}")

            if subnet_id in private_ids and subnet_az_cleaned == target_az_cleaned:
                <http://pulumi.log.info|pulumi.log.info>(f"Subnet ID={subnet_id} matches the target availability zone {target_az_cleaned} and is private.")
                return subnet_id  # Append this to match list
            else:
                <http://pulumi.log.info|pulumi.log.info>(f"Subnet ID={subnet_id} does NOT match the required criteria (Private & AZ={target_az_cleaned}).")
                return None

        matching_subnet = subnet.id.apply(lambda sid: subnet.availability_zone.apply(lambda saz: evaluate_subnet(sid, saz)))
        matching_subnets_output.append(matching_subnet)

    # After evaluating, we need to flatten the matching list and remove `None` values
    def filter_and_flatten(matching_subnet_outputs):
        # Filter out `None` values and return a plain list of matching subnet IDs
        matched = [subnet_id for subnet_id in matching_subnet_outputs if subnet_id is not None]
        if not matched:
            pulumi.log.warn(f"No matching subnets found in AZ {target_az}")
        else:
            <http://pulumi.log.info|pulumi.log.info>(f"Matched Subnets: {matched}")
        return matched

    # Using `Output.all()` to gather all results and flatten them into a list
    return pulumi.Output.all(*matching_subnets_output).apply(filter_and_flatten)
The "node_config" object is just a dictionary of stuff from the pulumi config. If I'm not dealing with a node group that has a capacity reservation ID, then we bail early.
So, this code, runs and it gives me output like this:
Copy code
Starting subnet filtering process.
    Total subnets provided: 6
    Private Subnet IDs provided: ['subnet-049611835250f0802', 'subnet-0bc4022303ba2ce30', 'subnet-0b898e1c212750d94']
    Target availability zone: us-west-2a
    Evaluating subnet: ID=subnet-049611835250f0802, AZ=us-west-2c
    Comparing with Target AZ=us-west-2a
    Subnet ID=subnet-049611835250f0802 does NOT match the required criteria (Private & AZ=us-west-2a).
    Evaluating subnet: ID=subnet-013ef29d83d628692, AZ=us-west-2c
    Comparing with Target AZ=us-west-2a
    Subnet ID=subnet-013ef29d83d628692 does NOT match the required criteria (Private & AZ=us-west-2a).
    Evaluating subnet: ID=subnet-0b898e1c212750d94, AZ=us-west-2c
    Comparing with Target AZ=us-west-2a
    Subnet ID=subnet-0b898e1c212750d94 does NOT match the required criteria (Private & AZ=us-west-2a).
    Evaluating subnet: ID=subnet-0d81b37841c9b9edd, AZ=us-west-2c
    Comparing with Target AZ=us-west-2a
    Subnet ID=subnet-0d81b37841c9b9edd does NOT match the required criteria (Private & AZ=us-west-2a).
    Evaluating subnet: ID=subnet-0bc4022303ba2ce30, AZ=us-west-2c
    Comparing with Target AZ=us-west-2a
    Subnet ID=subnet-0bc4022303ba2ce30 does NOT match the required criteria (Private & AZ=us-west-2a).
    Evaluating subnet: ID=subnet-0b73da73bb56d3941, AZ=us-west-2c
    Comparing with Target AZ=us-west-2a
    Subnet ID=subnet-0b73da73bb56d3941 does NOT match the required criteria (Private & AZ=us-west-2a).
    warning: No matching subnets found in AZ us-west-2a
Except that I know that
subnet-049611835250f0802
is in
us-west-2a
not
us-west-2c
. Before I go digging into github issues, can anyone see something I'm clearly doing wrong?
Yeah, I think this is a bug. I created a new EKS project and I got the same results: https://github.com/pulumi/pulumi-awsx/issues/1422
q
Thanks for filing the issue, I'll start looking into it right away!