Max Iskram
Max Iskram

Reputation: 197

AWS boto3: how to get hourly price of a specific instance id

I'm trying to write a python script using boto3 in order to get hourly prices of an instance, given the instance ID. I should remark that I'm not speaking about costs that you can get from cost explorer, I'm speaking about nominal hourly price, for example for an 'ec2' instance. I've already found some examples using "boto3.client('pricing',...)" and a bunch of parameters and filters as in:
https://www.saisci.com/aws/how-to-get-the-on-demand-price-of-ec2-instances-using-boto3-and-python/
which also requires region code to region name conversion.
I would like not to have to specify every instance detail and parameter for that query.
Can anybody help me to find a way to get that info just having the ec2 instance ID?
Thanks in advance.

Upvotes: 0

Views: 1459

Answers (2)

Ashley Kleynhans
Ashley Kleynhans

Reputation: 405

You have to specify most of the information but not all of it.

For example, region_name is optional if you:

  1. Have configured AWS CLI on the machine on which your Python script is running (ie. ~/.aws/config is present and the region is configured).

OR

  1. You are running the Python script on an AWS resource that has a role attached to it with a policy that allows you to retrieve the spot pricing information.

For example, I am able to run this script that retrieves my current spot instances and gets their current hourly cost, and calculates a bid price for me based on the spot price history for that particular instance type without specifying the region anywhere:

#!/usr/bin/env python3
import boto3
import json
from datetime import datetime
from datetime import timedelta
from collections import namedtuple


def get_current_pricing():
    pricing = []
    ec2_client = boto3.client('ec2')
    ec2_resource = boto3.resource('ec2')
    response = ec2_client.describe_spot_instance_requests()
    spot_instance_requests = response['SpotInstanceRequests']

    for instance_request in spot_instance_requests:
        if instance_request['State'] == 'active':
            instance = ec2_resource.Instance(instance_request['InstanceId'])

            for tag in instance.tags:
                if tag['Key'] == 'Name':
                    application = tag['Value']
                    break

            price = {
                'application': application,
                'instance_type': instance_request['LaunchSpecification']['InstanceType'],
                'current_price': float(instance_request['SpotPrice']),
                'bid_price': get_bid_price(instance_request['LaunchSpecification']['InstanceType'])
            }

            pricing.append(price)

    return pricing


def get_bid_price(instancetype):
    instance_types = [instancetype]
    start = datetime.now() - timedelta(days=1)
    ec2 = boto3.client('ec2')

    price_dict = ec2.describe_spot_price_history(
        StartTime=start,
        InstanceTypes=instance_types,
        ProductDescriptions=['Linux/UNIX']
    )

    if len(price_dict.get('SpotPriceHistory')) > 0:
        PriceHistory = namedtuple('PriceHistory', 'price timestamp')

        for item in price_dict.get('SpotPriceHistory'):
            price_list = [PriceHistory(round(float(item.get('SpotPrice')), 5), item.get('Timestamp'))]

        price_list.sort(key=lambda tup: tup.timestamp, reverse=True)

        bid_price = round(float(price_list[0][0]), 5)
        leeway = round(float(bid_price / 100 * 10), 5)
        bid_price = round(float(bid_price + leeway), 5)

        return bid_price
    else:
        raise ValueError(f'Invalid instance type: {instancetype} provided. '
                         'Please provide correct instance type.')


if __name__ == '__main__':
    current_pricing = get_current_pricing()
    print(json.dumps(current_pricing, indent=4, default=str))

Upvotes: 0

Mark B
Mark B

Reputation: 201078

You have to pass all that information. If you want to write a script that takes an instance ID and returns the hourly price, then you would first need to use the instance ID to lookup the instance details, and then pass those details to the pricing query.

Upvotes: 0

Related Questions