Skip to main content
Glama

CFM Tips - Cost Optimization MCP Server

by aws-samples
diagnose_cost_optimization_hub_v2.py11.1 kB
#!/usr/bin/env python3 """ Diagnostic script for Cost Optimization Hub issues - Updated with correct permissions """ import boto3 import json from botocore.exceptions import ClientError def check_cost_optimization_hub(): """Check Cost Optimization Hub status and common issues.""" print("🔍 Diagnosing Cost Optimization Hub Issues") print("=" * 50) # Test different regions where Cost Optimization Hub is available regions_to_test = ['us-east-1', 'us-west-2', 'eu-west-1', 'ap-southeast-1'] for region in regions_to_test: print(f"\n📍 Testing region: {region}") try: client = boto3.client('cost-optimization-hub', region_name=region) # Test 1: Check enrollment statuses (correct API call) print(" ✅ Testing enrollment statuses...") try: enrollment_response = client.list_enrollment_statuses() print(f" 📊 Enrollment Response: {json.dumps(enrollment_response, indent=2, default=str)}") # Check if any accounts are enrolled items = enrollment_response.get('items', []) if items: active_enrollments = [item for item in items if item.get('status') == 'Active'] if active_enrollments: print(f" ✅ Found {len(active_enrollments)} active enrollments") # Test 2: Try to list recommendations print(" ✅ Testing list recommendations...") try: recommendations = client.list_recommendations(maxResults=5) print(f" 📊 Found {len(recommendations.get('items', []))} recommendations") print(" ✅ Cost Optimization Hub is working correctly!") return True except ClientError as rec_error: print(f" ❌ Error listing recommendations: {rec_error.response['Error']['Code']} - {rec_error.response['Error']['Message']}") else: print(" ⚠️ No active enrollments found") print(" 💡 You need to enable Cost Optimization Hub in the AWS Console") else: print(" ⚠️ No enrollment information found") print(" 💡 Cost Optimization Hub may not be set up for this account") except ClientError as enrollment_error: error_code = enrollment_error.response['Error']['Code'] error_message = enrollment_error.response['Error']['Message'] if error_code == 'AccessDeniedException': print(" ❌ Access denied - check IAM permissions") print(" 💡 Required permissions: cost-optimization-hub:ListEnrollmentStatuses") elif error_code == 'ValidationException': print(f" ❌ Validation error: {error_message}") else: print(f" ❌ Error: {error_code} - {error_message}") except Exception as e: print(f" ❌ Failed to create client for region {region}: {str(e)}") return False def check_iam_permissions(): """Check IAM permissions for Cost Optimization Hub.""" print("\n🔐 Checking IAM Permissions") print("=" * 30) try: # Get current user/role sts_client = boto3.client('sts') identity = sts_client.get_caller_identity() print(f"Current identity: {identity.get('Arn', 'Unknown')}") # Correct required actions for Cost Optimization Hub required_actions = [ 'cost-optimization-hub:ListEnrollmentStatuses', 'cost-optimization-hub:UpdateEnrollmentStatus', 'cost-optimization-hub:GetPreferences', 'cost-optimization-hub:UpdatePreferences', 'cost-optimization-hub:GetRecommendation', 'cost-optimization-hub:ListRecommendations', 'cost-optimization-hub:ListRecommendationSummaries' ] print("\nRequired permissions for Cost Optimization Hub:") for action in required_actions: print(f" - {action}") print("\nMinimal permissions for read-only access:") minimal_actions = [ 'cost-optimization-hub:ListEnrollmentStatuses', 'cost-optimization-hub:ListRecommendations', 'cost-optimization-hub:GetRecommendation', 'cost-optimization-hub:ListRecommendationSummaries' ] for action in minimal_actions: print(f" - {action}") except Exception as e: print(f"Error checking IAM: {str(e)}") def test_individual_apis(): """Test individual Cost Optimization Hub APIs.""" print("\n🧪 Testing Individual APIs") print("=" * 30) try: client = boto3.client('cost-optimization-hub', region_name='us-east-1') # Test 1: List Enrollment Statuses print("\n1. Testing list_enrollment_statuses...") try: response = client.list_enrollment_statuses() print(f" ✅ Success: Found {len(response.get('items', []))} enrollment records") except ClientError as e: print(f" ❌ Failed: {e.response['Error']['Code']} - {e.response['Error']['Message']}") # Test 2: List Recommendations print("\n2. Testing list_recommendations...") try: response = client.list_recommendations(maxResults=5) print(f" ✅ Success: Found {len(response.get('items', []))} recommendations") except ClientError as e: print(f" ❌ Failed: {e.response['Error']['Code']} - {e.response['Error']['Message']}") # Test 3: List Recommendation Summaries print("\n3. Testing list_recommendation_summaries...") try: response = client.list_recommendation_summaries(maxResults=5) print(f" ✅ Success: Found {len(response.get('items', []))} summaries") except ClientError as e: print(f" ❌ Failed: {e.response['Error']['Code']} - {e.response['Error']['Message']}") except Exception as e: print(f"Error testing APIs: {str(e)}") def provide_correct_iam_policy(): """Provide the correct IAM policy for Cost Optimization Hub.""" print("\n📋 Correct IAM Policy") print("=" * 25) policy = { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "cost-optimization-hub:ListEnrollmentStatuses", "cost-optimization-hub:UpdateEnrollmentStatus", "cost-optimization-hub:GetPreferences", "cost-optimization-hub:UpdatePreferences", "cost-optimization-hub:GetRecommendation", "cost-optimization-hub:ListRecommendations", "cost-optimization-hub:ListRecommendationSummaries" ], "Resource": "*" } ] } print("Full IAM Policy:") print(json.dumps(policy, indent=2)) minimal_policy = { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "cost-optimization-hub:ListEnrollmentStatuses", "cost-optimization-hub:ListRecommendations", "cost-optimization-hub:GetRecommendation", "cost-optimization-hub:ListRecommendationSummaries" ], "Resource": "*" } ] } print("\nMinimal Read-Only Policy:") print(json.dumps(minimal_policy, indent=2)) def provide_solutions(): """Provide solutions for common Cost Optimization Hub issues.""" print("\n🛠️ Updated Solutions") print("=" * 20) solutions = [ { "issue": "AccessDeniedException", "solution": [ "1. Add the correct IAM permissions (see policy above)", "2. The service uses different permission names than other AWS services", "3. Use 'cost-optimization-hub:ListEnrollmentStatuses' not 'GetEnrollmentStatus'", "4. Attach the policy to your IAM user/role" ] }, { "issue": "No enrollment found", "solution": [ "1. Go to AWS Console → Cost Optimization Hub", "2. Enable the service for your account", "3. Wait for enrollment to complete", "4. URL: https://console.aws.amazon.com/cost-optimization-hub/" ] }, { "issue": "Service not available", "solution": [ "1. Cost Optimization Hub is only available in specific regions", "2. Use us-east-1, us-west-2, eu-west-1, or ap-southeast-1", "3. The service may not be available in your region yet" ] }, { "issue": "No recommendations found", "solution": [ "1. Cost Optimization Hub needs time to analyze your resources", "2. Ensure you have resources running for at least 14 days", "3. The service needs sufficient usage data to generate recommendations", "4. Check if you have any EC2, RDS, or other supported resources" ] } ] for solution in solutions: print(f"\n🔧 {solution['issue']}:") for step in solution['solution']: print(f" {step}") def main(): """Main diagnostic function.""" print("AWS Cost Optimization Hub Diagnostic Tool v2") print("=" * 50) try: # Run diagnostics hub_working = check_cost_optimization_hub() check_iam_permissions() test_individual_apis() provide_correct_iam_policy() provide_solutions() print("\n" + "=" * 60) if hub_working: print("✅ DIAGNOSIS: Cost Optimization Hub appears to be working!") else: print("❌ DIAGNOSIS: Cost Optimization Hub needs to be set up.") print("\n📝 Next Steps:") print("1. Apply the correct IAM policy shown above") print("2. Enable Cost Optimization Hub in the AWS Console if needed") print("3. Use the updated MCP server (mcp_server_fixed_v3.py)") print("4. Test with the enrollment status tool first") except Exception as e: print(f"\n❌ Diagnostic failed: {str(e)}") print("Please check your AWS credentials and try again.") if __name__ == "__main__": main()

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aws-samples/sample-cfm-tips-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server