Last active
May 9, 2023 11:00
-
-
Save omerh/302a9615d6d24eeead2449b36c10b13e to your computer and use it in GitHub Desktop.
Revisions
-
Omer Haim revised this gist
May 9, 2023 . 1 changed file with 3 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -8,18 +8,16 @@ def get_ec2_spot_pricing(instance_type, region_code): client = boto3.client('ec2', region_name=region_code) today_date = datetime.utcnow() response = client.get_paginator('describe_spot_price_history').paginate( InstanceTypes=[instance_type], ProductDescriptions=['Linux/UNIX'], StartTime=today_date, EndTime=today_date,).build_full_result() return response['SpotPriceHistory'] def get_region_name(region_code): endpoint_file = resource_filename('botocore', 'data/endpoints.json') with open(endpoint_file, 'r') as f: endpoint_data = json.load(f) @@ -58,7 +56,7 @@ def get_ec2_instance_hourly_price(region_code, ] pricing_client = boto3.client('pricing', region_name='us-east-1') response = pricing_client.get_paginator('get_products').paginate(ServiceCode='AmazonEC2', Filters=filters).build_full_result() for price in response['PriceList']: price = json.loads(price) -
Omer Haim created this gist
May 9, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,145 @@ import csv from datetime import datetime import boto3 import json from pkg_resources import resource_filename def get_ec2_spot_pricing(instance_type, region_code): client = boto3.client('ec2', region_name=region_code) today_date = datetime.utcnow() response = client.describe_spot_price_history( InstanceTypes=[instance_type], ProductDescriptions=['Linux/UNIX'], StartTime=today_date, EndTime=today_date, ) return response['SpotPriceHistory'] def get_region_name(region_code): endpoint_file = resource_filename('botocore', 'data/endpoints.json') with open(endpoint_file, 'r') as f: endpoint_data = json.load(f) region_name = endpoint_data['partitions'][0]['regions'][region_code]['description'] region_name = region_name.replace('Europe', 'EU') return region_name def get_ec2_instance_hourly_price(region_code, instance_type, operating_system, preinstalled_software='NA', tenancy='Shared', is_byol=False): region_name = get_region_name(region_code) if is_byol: license_model = 'Bring your own license' else: license_model = 'No License required' if tenancy == 'Host': capacity_status = 'AllocatedHost' else: capacity_status = 'Used' filters = [ {'Type': 'TERM_MATCH', 'Field': 'termType', 'Value': 'OnDemand'}, {'Type': 'TERM_MATCH', 'Field': 'capacitystatus', 'Value': capacity_status}, {'Type': 'TERM_MATCH', 'Field': 'location', 'Value': region_name}, {'Type': 'TERM_MATCH', 'Field': 'instanceType', 'Value': instance_type}, {'Type': 'TERM_MATCH', 'Field': 'tenancy', 'Value': tenancy}, {'Type': 'TERM_MATCH', 'Field': 'operatingSystem', 'Value': operating_system}, {'Type': 'TERM_MATCH', 'Field': 'preInstalledSw', 'Value': preinstalled_software}, {'Type': 'TERM_MATCH', 'Field': 'licenseModel', 'Value': license_model}, ] pricing_client = boto3.client('pricing', region_name='us-east-1') response = pricing_client.get_products(ServiceCode='AmazonEC2', Filters=filters) for price in response['PriceList']: price = json.loads(price) for on_demand in price['terms']['OnDemand'].values(): for price_dimensions in on_demand['priceDimensions'].values(): price_value = price_dimensions['pricePerUnit']['USD'] return float(price_value) return None def get_all_instances_offering(region): ec2_client = boto3.client('ec2', region_name=region) response = ec2_client.get_paginator('describe_instance_type_offerings').paginate().build_full_result() return response['InstanceTypeOfferings'] def write_to_csv(result_list, region_code): # Get all possible keys all_keys = [] for d in result_list: for key in d.keys(): if key not in all_keys: all_keys.append(key) for d in result_list: for key in all_keys: d.setdefault(key, None) file_name_with_date = "ec2-report-{}-{}.csv".format(region_code, datetime.now().strftime("%Y%m%d%H%M%S")) with open(file_name_with_date, 'w', newline='') as csvfile: writer = csv.DictWriter(csvfile, fieldnames=all_keys) writer.writeheader() for row in result_list: writer.writerow(row) if __name__ == "__main__": region_code = 'us-east-1' full_pricing = [] result = {} # Get all instance offerings in the region offerings = get_all_instances_offering(region_code) # debug # i = 1 for offering in offerings: # Get the hourly price of the instance ec2_instance_price = get_ec2_instance_hourly_price( region_code=region_code, instance_type=offering['InstanceType'], operating_system='Linux', ) # Create a dict with the instance offering and the price on_demand = { "region": region_code, "instance_type": offering['InstanceType'], "on-demand_price": ec2_instance_price, } # Add the result to temp r dict r = on_demand.copy() # Get spot price for the instance type in the region spot_pricing = get_ec2_spot_pricing(instance_type=offering['InstanceType'], region_code=region_code) # Iterate over the spot result, as each AZ has its offering for record in spot_pricing: spot_price_az = { "instance_type": offering['InstanceType'], record['AvailabilityZone']: record['SpotPrice'], record['AvailabilityZone'] + "-price-diff-percent": (float(record['SpotPrice']) - float( ec2_instance_price)) / float(ec2_instance_price) * 100, } # Update the r dict with the spot price in the AZ, and its diff in percent r.update(spot_price_az) # Add the result to the full pricing list full_pricing.append(r) # Working indicator print(".", end="", flush=True) # debug # i = i + 1 # if i > 2: # break write_to_csv(full_pricing, region_code)