使用 boto3 获取给定 EC2 实例类型的当前价格

新手上路,请多包涵

现在 AWS 有一个定价 API,如何使用 Boto3 获取给定 的按需 EC2 实例类型(例如 t2.micro)、 区域(例如 eu-west-1)和 操作系统(例如 Linux)的当前每小时价格)?我只想退回价格。根据我的理解,拥有这四条信息应该足以过滤出一个单一的结果。

但是,我见过的所有示例都从 API 中获取大量数据列表,这些数据必须进行后处理才能获得我想要的内容。我想在返回数据之前在 API 端过滤数据。

原文由 toringe 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 896
2 个回答

这是我最终得到的解决方案。使用 Boto3 自己的定价 API 以及针对实例类型、区域和操作系统的过滤器。 API 仍然会返回很多信息,所以我需要做一些后期处理。

 import boto3
import json
from pkg_resources import resource_filename

# Search product filter. This will reduce the amount of data returned by the
# get_products function of the Pricing API
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 instance
def get_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 name. Even though the API data contains
# regionCode field, it will not return accurate data. However using the location
# field will, but then we need to translate the region code into a region name.
# You could skip this by using the region names in your code directly, but most
# other APIs are using the region code.
def get_region_name(region_code):
    default_region = 'US East (N. Virginia)'
    endpoint_file = resource_filename('botocore', 'data/endpoints.json')
    try:
        with open(endpoint_file, 'r') as f:
            data = json.load(f)
        # Botocore is using Europe while Pricing API using EU...sigh...
        return data['partitions'][0]['regions'][region_code]['description'].replace('Europe', 'EU')
    except IOError:
        return default_region

# Use AWS Pricing API through Boto3
# API only has us-east-1 and ap-south-1 as valid endpoints.
# It doesn't have any impact on your selected region for your instance.
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'), 't3.micro', 'Linux')
print(price)

此示例相当快地输出 0.0114000000 (以美元为单位的每小时价格)。 (此数字经验证与撰写本文时 此处 列出的当前值相匹配)

原文由 toringe 发布,翻译遵循 CC BY-SA 4.0 许可协议

如果您不喜欢本机函数,请查看 Lyft 的 Python awspricing 库。这是一个例子:

 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

我建议启用缓存(请参阅 AWSPRICING_USE_CACHE),否则速度会很慢。

原文由 jarmod 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进