technicalmedium
Implement a Python function that uses AWS SDK (Boto3) to list all S3 buckets in a given AWS region, filter them by a specific tag key-value pair, and then print the names of the filtered buckets. Include error handling for API calls.
technical screen · 10-15 minutes
How to structure your answer
MECE Framework: 1. Initialization: Import boto3, define function signature with region and tag key-value. 2. S3 Client: Create a Boto3 S3 client for the specified region. 3. List Buckets: Call list_buckets() API. Implement try-except for ClientError and general exceptions. 4. Iterate & Filter: Loop through each bucket. For each, use get_bucket_tagging() to retrieve tags. Implement try-except for NoSuchTagSet and ClientError. 5. Tag Matching: Check if the desired tag key-value pair exists. 6. Output: Print names of matching buckets. 7. Error Handling: Provide informative messages for API failures or missing tags.
Sample answer
import boto3
from botocore.exceptions import ClientError
def list_s3_buckets_by_tag(region_name, tag_key, tag_value):
"""
Lists S3 buckets in a given AWS region, filtered by a specific tag key-value pair.
"""
print(f"Searching for S3 buckets in region '{region_name}' with tag '{tag_key}:{tag_value}'...")
try:
s3_client = boto3.client('s3', region_name=region_name)
response = s3_client.list_buckets()
filtered_buckets = []
for bucket in response.get('Buckets', []):
bucket_name = bucket['Name']
try:
tagging_response = s3_client.get_bucket_tagging(Bucket=bucket_name)
tags = tagging_response.get('TagSet', [])
if any(t['Key'] == tag_key and t['Value'] == tag_value for t in tags):
filtered_buckets.append(bucket_name)
except ClientError as e:
if e.response['Error']['Code'] == 'NoSuchTagSet':
# Bucket has no tags, skip
pass
else:
print(f"Error retrieving tags for bucket '{bucket_name}': {e}")
except Exception as e:
print(f"An unexpected error occurred for bucket '{bucket_name}': {e}")
if filtered_buckets:
print("\nFiltered S3 Buckets:")
for bucket_name in filtered_buckets:
print(f"- {bucket_name}")
else:
print("\nNo S3 buckets found matching the criteria.")
except ClientError as e:
print(f"AWS Client Error in region '{region_name}': {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
# Example Usage:
# list_s3_buckets_by_tag('us-east-1', 'Environment', 'Development')
# list_s3_buckets_by_tag('eu-west-1', 'Project', 'DataLake')
Key points to mention
- • **Boto3 Client Initialization**: Correctly initializing the S3 client with the specified region.
- • **`list_buckets()` API Call**: Understanding that `list_buckets()` returns all buckets globally, not just region-specific ones, and the need to filter by region if required (though the prompt implies filtering by tags *after* listing all).
- • **`get_bucket_tagging()` API Call**: Knowing how to retrieve tags for individual buckets.
- • **Error Handling (ClientError)**: Specifically handling `NoSuchTagSet` or general `ClientError` when a bucket might not have tags.
- • **Tag Filtering Logic**: Implementing the correct logic to iterate through tags and match both key and value.
- • **Resource-Based vs. Account-Based APIs**: Differentiating between global (e.g., `list_buckets`) and regional (e.g., `get_bucket_tagging` which requires a region context for the client) S3 operations.
Common mistakes to avoid
- ✗ Forgetting to handle `ClientError` when a bucket does not have any tags, leading to program crashes.
- ✗ Assuming `list_buckets()` is region-specific; it lists all buckets in the account, requiring additional logic if region-specific listing is truly desired (though not explicitly asked for here).
- ✗ Incorrectly parsing the response from `get_bucket_tagging()`, especially the structure of the `TagSet`.
- ✗ Lack of proper credential configuration or IAM permissions, leading to `AccessDenied` errors.
- ✗ Hardcoding credentials instead of using best practices (e.g., IAM roles, environment variables).