Skip to content Skip to sidebar Skip to footer

Use Boto3 To Get Current Price For Given Ec2 Instance Type

Now that AWS have a Pricing API, how could one use Boto3 to fetch the current hourly price for a given on-demand EC2 instance type (e.g. t2.micro), region (e.g. eu-west-1) and oper

Solution 1:

Here is the solution I ended up with. Using Boto3's own Pricing API with a filter for the instance type, region and operating system. The API still returns a lot of information, so I needed to do a bit of post-processing.

import boto3
import json
from pkg_resources import resource_filename

# Search product filter
FLT = '[{{"Field": "tenancy", "Value": "shared", "Type": "TERM_MATCH"}},'\
      '{{"Field": "operatingSystem", "Value": "{o}", "Type": "TERM_MATCH"}},'\
      '{{"Field": "preInstalledSw", "Value": "NA", "Type": "TERM_MATCH"}},'\
      '{{"Field": "instanceType", "Value": "{t}", "Type": "TERM_MATCH"}},'\
      '{{"Field": "location", "Value": "{r}", "Type": "TERM_MATCH"}},'\
      '{{"Field": "capacitystatus", "Value": "Used", "Type": "TERM_MATCH"}}]'# Get current AWS price for an on-demand instancedefget_price(region, instance, os):
    f = FLT.format(r=region, t=instance, o=os)
    data = client.get_products(ServiceCode='AmazonEC2', Filters=json.loads(f))
    od = json.loads(data['PriceList'][0])['terms']['OnDemand']
    id1 = list(od)[0]
    id2 = list(od[id1]['priceDimensions'])[0]
    return od[id1]['priceDimensions'][id2]['pricePerUnit']['USD']

# Translate region code to region namedefget_region_name(region_code):
    default_region = 'EU (Ireland)'
    endpoint_file = resource_filename('botocore', 'data/endpoints.json')
    try:
        withopen(endpoint_file, 'r') as f:
            data = json.load(f)
        return data['partitions'][0]['regions'][region_code]['description']
    except IOError:
        return default_region


# Use AWS Pricing API at US-East-1
client = boto3.client('pricing', region_name='us-east-1')

# Get current price for a given instance, region and os
price = get_price(get_region_name('eu-west-1'), 'c5.xlarge', 'Linux')
print(price)

This example outputs 0.1920000000 (hourly price in USD) fairly quickly. But any further optimizations would indeed be appreciated.

Solution 2:

If you don't like the native function, then look at Lyft's awspricing library for Python. Here's an example:

import awspricing

ec2_offer = awspricing.offer('AmazonEC2')

p = ec2_offer.ondemand_hourly(
  't2.micro',
  operating_system='Linux',
  region='eu-west-1'
)

print(p) # 0.0126

I'd recommend enabling caching (see AWSPRICING_USE_CACHE) otherwise it will be slow.

Solution 3:

I have updated toringe's solution a bit to handle different key errors

defprice_information(self, instance_type, os, region):
        # Search product filter
        FLT = '[{{"Field": "operatingSystem", "Value": "{o}", "Type": "TERM_MATCH"}},' \
              '{{"Field": "instanceType", "Value": "{t}", "Type": "TERM_MATCH"}}]'
    
        f = FLT.format(t=instance_type, o=os)
        try:
            data = self.pricing_client.get_products(ServiceCode='AmazonEC2', Filters=json.loads(f))
            instance_price = 0for price in data['PriceList']:
                try:
                    first_id =  list(eval(price)['terms']['OnDemand'].keys())[0]
                    price_data = eval(price)['terms']['OnDemand'][first_id]
                    second_id = list(price_data['priceDimensions'].keys())[0]
                    instance_price = price_data['priceDimensions'][second_id]['pricePerUnit']['USD']
                    iffloat(price) > 0:
                        breakexcept Exception as e:
                    print(e)
            print(instance_price)
            return instance_price
        except Exception as e:
            print(e)
            return0

Post a Comment for "Use Boto3 To Get Current Price For Given Ec2 Instance Type"