AWS: How to get the On Demand price of a EC2 instance using Python and Boto3

AWS EC2 price instance

3 min read | by Jordi Prats

We can use python with Boto3 to retrieve the current On Demand price for a given instance type.

To do so we are going to use the Amazon Web Services Price List Service API. This API, at the time of this writing, it only provides the following endpoints * *

The following python code has the us-east-1 endpoint hardcoded on it.

The following function accepts the following arguments:

  • instance_type: Instance type that we want to get it's pricing
  • region: AWS region to use (default: eu-west-1)
  • os: Operating System of the target Instance: Linux (default), Windows, Red Hat Enterprise Linux with HA, RHEL or SUSE*
  • preinstalled_software: Only for preinstalled SQL Server: NA (default, without preinstalled software), SQL Ent, SQL Std or SQL Web
  • tenancy: For specifying the tenancy of the target EC2 Instance: Shared (default, Shared Hardware), Dedicated (Dedicated Instance or single-tenant hardware) or Host (an isolated server with configurations under your control)
  • byol: Determines whether the target EC2 Instance price is for Bring your own license (default: False)

The code is the following:

def current_price(instance_type, region='eu-west-1', os='Linux', preinstalled_software='NA', tenancy='Shared', byol=False):

  ec2_client = boto3.client(service_name='ec2', region_name=region)

  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'][boto3.session.Session().region_name]['description'].replace('Europe', 'EU')

  filters = [
        {'Type': 'TERM_MATCH', 'Field': 'termType', 'Value': 'OnDemand'},
        {'Type': 'TERM_MATCH', 'Field': 'capacitystatus', 'Value': 'AllocatedHost' if tenancy == 'Host' else 'Used'},
        {'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': os},
        {'Type': 'TERM_MATCH', 'Field': 'preInstalledSw', 'Value': preinstalled_software},
        {'Type': 'TERM_MATCH', 'Field': 'licenseModel', 'Value': 'Bring your own license' if byol else 'No License required'},

  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():
        return { 
                'instance_type': instance_type, 
                'region': region, 
                'os': os, 
                'preinstalled_software': preinstalled_software, 
                'tenancy': tenancy, 
                'byol': byol, 
                'price': price_dimensions['pricePerUnit']['USD'], 
                'effective': on_demand['effectiveDate']

This function returns a dictionary with all the parameters together with the price it has retrieved (in USD) and it's effective date.

Using the following python code we can print it's results:

out_format='{: <30} {: <30} {: <30} {: <30} {}'

pricing_result = current_price(instance_type='t1.micro', region='us-west-2')

print(out_format.format('Instance Type', 'OS', 'Region', 'OnDemand Price', "effective"))

It's going to give us the following output:

Instance Type                  OS                             Region                         OnDemand Price                 effective
t1.micro                       Linux                          us-west-2                      0.0200000000                   2022-05-01T00:00:00Z

Posted on 31/05/2022