agent: |
p7esvHfNzElz5LFA2wqgFetch Rightsizing Recommendations for AWS EBS Volumes
Fetch Rightsizing Recommendations for AWS EBS Volumes
There was a problem that the LLM was not able to address. Please rephrase your prompt and try again.
This task involves analyzing EBS volume usage to offer configuration changes for cost efficiency and performance improvement, based on historical data analysis.
inputs
outputs
import boto3
import json
from datetime import datetime, timezone
creds = _get_creds(cred_label)['creds']
access_key = creds['username']
secret_key = creds['password']
# Define the pricing_client at the beginning of your script to ensure it's available globally
pricing_client = boto3.client('pricing', aws_access_key_id=access_key, aws_secret_access_key=secret_key, region_name='us-east-1')
def get_ebs_volume_recommendations(region_name=None):
"""
Fetch EBS volume recommendations from AWS Compute Optimizer for a specific region or all regions.
"""
if region_name:
regions = [region_name]
else:
# Initialize a client for the EC2 service to fetch all regions
ec2_client = boto3.client('ec2', aws_access_key_id=access_key, aws_secret_access_key=secret_key, region_name='us-east-1')
regions_response = ec2_client.describe_regions()
regions = [region['RegionName'] for region in regions_response['Regions']]
recommendations = []
for region in regions:
try:
# Initialize Compute Optimizer client for each region
compute_optimizer_client = boto3.client('compute-optimizer', aws_access_key_id=access_key, aws_secret_access_key=secret_key, region_name=region)
next_token = None
while True:
params = {}
if next_token:
params['NextToken'] = next_token
response = compute_optimizer_client.get_ebs_volume_recommendations(**params)
recommendations.extend(response.get('volumeRecommendations', []))
next_token = response.get('NextToken', None)
if not next_token:
break
except Exception as e:
print(f"Error fetching EBS volume recommendations for region {region}: {e}")
return recommendations
def get_ebs_price(volume_type, size_gb, region):
# Mapping AWS region to the Pricing API format
region_name_map = {
"us-east-1": "US East (N. Virginia)",
"us-east-2": "US East (Ohio)",
"us-west-1": "US West (N. California)",
"us-west-2": "US West (Oregon)",
"af-south-1": "Africa (Cape Town)",
"ap-east-1": "Asia Pacific (Hong Kong)",
"ap-south-1": "Asia Pacific (Mumbai)",
"ap-northeast-3": "Asia Pacific (Osaka)",
"ap-northeast-2": "Asia Pacific (Seoul)",
"ap-southeast-1": "Asia Pacific (Singapore)",
"ap-southeast-2": "Asia Pacific (Sydney)",
"ap-northeast-1": "Asia Pacific (Tokyo)",
"ca-central-1": "Canada (Central)",
"eu-central-1": "EU (Frankfurt)",
"eu-west-1": "EU (Ireland)",
"eu-west-2": "EU (London)",
"eu-south-1": "EU (Milan)",
"eu-west-3": "EU (Paris)",
"eu-north-1": "EU (Stockholm)",
"me-south-1": "Middle East (Bahrain)",
"sa-east-1": "South America (São Paulo)"}
region_name = region_name_map.get(region, region)
#print(f"searching for region {region_name}") # for debugging
try:
price_response = pricing_client.get_products(
ServiceCode='AmazonEC2',
Filters=[
{'Type': 'TERM_MATCH', 'Field': 'volumeApiName', 'Value': volume_type}, # Adjusted to 'volumeApiName'
{'Type': 'TERM_MATCH', 'Field': 'location', 'Value': region_name},
{'Type': 'TERM_MATCH', 'Field': 'productFamily', 'Value': 'Storage'}
],
MaxResults=1 # Increased MaxResults to ensure broader search results
)
#print(price_response) # for debugging
# Ensure there's at least one price listed
if price_response['PriceList']:
# Assuming the first price item's details are representative
price_data = json.loads(price_response['PriceList'][0])
terms = price_data.get('terms', {}).get('OnDemand', {})
if terms:
price_dimensions = next(iter(terms.values()))['priceDimensions']
price_per_gb = next(iter(price_dimensions.values()))['pricePerUnit']['USD']
# Calculate total price based on the volume size
total_price = float(price_per_gb) * size_gb
return total_price
else:
print("No pricing terms found.")
return None
except Exception as e:
print(f"Error fetching price for EBS volume: {e}")
return None
def process_recommendations(recommendations):
for recommendation in recommendations:
volume_arn = recommendation['volumeArn']
region = volume_arn.split(':')[3] # for pricing api query
current_configuration = recommendation['currentConfiguration']
finding = recommendation['finding']
finding_reasons_codes = recommendation.get('findingReasonCodes', [])
print(f"Volume ARN: {volume_arn}")
print(f"Region: {region}")
print(f"Current Configuration: {json.dumps(current_configuration, indent=2)}")
print(f"Finding: {finding} {' | '.join(finding_reasons_codes) if finding_reasons_codes else ''}")
if 'volumeRecommendationOptions' in recommendation:
for option in recommendation['volumeRecommendationOptions']:
configuration = option['configuration']
performance_risk = option.get('performanceRisk', 'N/A')
rank = option['rank']
volume_type = configuration['volumeType']
size_gb = configuration['volumeSize']
current_price = get_ebs_price(current_configuration['volumeType'], current_configuration['volumeSize'], region)
recommended_price = get_ebs_price(volume_type, size_gb, region)
print(f"\tRecommended Configuration: {json.dumps(configuration, indent=4)}")
print(f"\tPerformance Risk: {performance_risk}")
print(f"\tRank: {rank}")
print(f"\tCurrent Price: ${current_price} per month")
print(f"\tRecommended Price: ${recommended_price} per month")
# Calculate and print savings
if current_price and recommended_price:
savings = current_price - recommended_price
print(f"\tEstimated Monthly Savings: ${savings:.2f}")
print("-" * 60)
else:
print("\tNo recommendation options provided.")
print("-" * 60)
# Example usage
#region_name_to_search_recommendations = 'us-east-1' # Set to None for all regions
recommendations = get_ebs_volume_recommendations(region_name_to_search_recommendations)
if recommendations:
print("Processing Recommendations")
process_recommendations(recommendations)
else:
print("No EBS volume recommendations available.")
copied