Unexpected Result from Asynchronous Function Checking DynamoDB Tables in Multiple AWS Regions

30 views Asked by At

I'm encountering an unexpected behavior with an asynchronous Python function designed to check entries in two DynamoDB tables across multiple AWS regions. Despite specifying region acceptability for failure cases, the function will sometimes return a result that contradicts the given acceptability criteria. When I run my Audit Script it worked 170 out of 175 accounts.

The function check_account_in_dynamodb_tables is supposed to query two DynamoDB tables across specified AWS regions (us-east-1, us-east-2, ca-central-1) for a given account ID. It should return a dictionary with keys formatted as {region}:{table_name} and values indicating the result of the check (Pass, Fail, Accept, Error), taking into account a region_acceptability dictionary that specifies whether a failure in a particular region is "Accept" or "Not Accept".

3 of the 5 checks that gave the incorrect Acceptation received this as the region_acceptability:

{'us-east-1': 'Not Accept', 'us-east-2': 'Accept', 'ca-central-1': 'Accept'}

I expected the function to mark any failures in us-east-1 as "Fail, Pass, or Error", but instead, it returned:

us-east-1:CustomConfigEC2PublicIPRemediationTable: Accept

Here is the relevant function:

async def check_account_in_dynamodb_tables(session, account_id, region_acceptability):
"""
Check if the given account_id is listed in two DynamoDB tables across multiple regions
and return individual results for each, considering region acceptability for failure cases.

:param session: An aioboto3 AWS session object
:param account_id: The AWS account ID to check
:param region_acceptability: List of regions where failure is deemed acceptable
:return: Dictionary with the results for each table in each region
"""
regions = ['us-east-1', 'us-east-2', 'ca-central-1']
tables = ["CustomConfigEC2PublicIPRemediationTable", "CustomConfigPublicNLBRemediationTable"]
results = {}

for region in regions:
    try:
        # Initialize the DynamoDB client for the specific region
        async with session.client('dynamodb', region_name=region) as dynamodb:
            for table_name in tables:
                key = f"{region}:{table_name}"  # Format the key as 'region:table_name'
                try:
                    #query the DynamoDB table
                    response = await dynamodb.query(
                        TableName=table_name,
                        KeyConditionExpression='AWSACCOUNTID = :account_id',
                        ExpressionAttributeValues={
                            ':account_id': {'S': account_id}
                        }
                    )
                    # Determine result based on query response and region acceptability
                    if 'Items' in response and len(response['Items']) > 0:
                        results[key] = "Pass"
                    else:
                        results[key] = "Accept" if region in region_acceptability else "Fail"
                except Exception as e:
                    logging.error(f"An error occurred while querying {table_name} in {region}: {e}")
                    results[key] = "Accept" if region in region_acceptability else "Error"
    except Exception as e:
            logging.error(f"Access Error for: {region}: {e}")
            for table_name in tables:
                key = f"{region}:{table_name}"  # Format the key as 'region:table_name'
                results[key] = "Accept" if region in region_acceptability else "Error"

return results

So my question is why is the function returning "Accept" for us-east-1 when the region_acceptability explicitly marks it as "Not Accept"?

Environment: asyncio httpx Python 3.8+ aioboto3

0

There are 0 answers