如何将EC2实例映射到价格列表查询中的对应产品条目?
关联EC2实例与Pricing产品条目的方法
AWS没有直接的API能一键关联EC2实例和对应的Pricing产品条目,必须通过匹配关键属性手动关联,核心是从两边数据中提取共同的标识字段。
核心匹配字段
从EC2实例信息和Pricing返回结果中,需匹配以下核心维度:
- 区域:EC2的
RegionCode对应Pricing产品条目中product.attributes.regionCode - 实例类型:EC2的
InstanceType对应Pricing产品条目中product.attributes.instanceType - 操作系统:EC2实例的
ImageId需要先通过DescribeImagesCommand获取镜像的PlatformDetails(如Linux、Windows),再对应Pricing的product.attributes.operatingSystem - 计费模式:按需实例对应Pricing的
termType: "OnDemand",预留实例对应termType: "Reserved"
具体实现步骤(NodeJS示例)
1. 补充获取EC2实例的操作系统信息
先通过EC2客户端获取镜像对应的操作系统:
const { DescribeImagesCommand } = require("@aws-sdk/client-ec2"); // 传入已初始化的ec2Client实例 const getImageOs = async (imageId, ec2Client) => { const command = new DescribeImagesCommand({ ImageIds: [imageId] }); const response = await ec2Client.send(command); // 兼容部分镜像无PlatformDetails的情况 return response.Images[0].PlatformDetails || "Linux"; };
2. 精准调用Pricing的GetProductsCommand
通过Filters参数缩小返回范围,减少后续匹配工作量:
const { GetProductsCommand } = require("@aws-sdk/client-pricing"); // 传入已初始化的pricingClient实例 const getInstancePricing = async (regionCode, instanceType, os, pricingClient) => { const command = new GetProductsCommand({ ServiceCode: "AmazonEC2", Filters: [ { Type: "TERM_MATCH", Field: "regionCode", Value: regionCode }, { Type: "TERM_MATCH", Field: "instanceType", Value: instanceType }, { Type: "TERM_MATCH", Field: "operatingSystem", Value: os }, { Type: "TERM_MATCH", Field: "tenancy", Value: "Shared" }, // 按需实例默认共享租户,按需调整 { Type: "TERM_MATCH", Field: "preInstalledSw", Value: "NA" } // 无预装软件,按需调整 ] }); const response = await pricingClient.send(command); return response.PriceList; };
3. 匹配EC2实例与价格条目
遍历EC2实例列表,结合操作系统信息匹配对应的价格条目:
// 传入从DescribeInstancesCommand获取的ec2Instances列表,以及初始化好的ec2Client、pricingClient const matchInstancesWithPricing = async (ec2Instances, ec2Client, pricingClient) => { return Promise.all(ec2Instances.map(async (instance) => { const os = await getImageOs(instance.ImageId, ec2Client); const priceList = await getInstancePricing(instance.RegionCode, instance.InstanceType, os, pricingClient); // 匹配按需价格条目(示例) const matchedPriceItem = priceList.find(item => { const parsedItem = JSON.parse(item); const product = parsedItem.product; const hasOnDemandTerms = Object.keys(parsedItem.terms.OnDemand || {}).length > 0; return product.attributes.regionCode === instance.RegionCode && product.attributes.instanceType === instance.InstanceType && product.attributes.operatingSystem === os && hasOnDemandTerms; }); // 提取单价(按需实例的每小时价格) const unitPrice = matchedPriceItem ? (() => { const parsedItem = JSON.parse(matchedPriceItem); const onDemandTerm = Object.values(parsedItem.terms.OnDemand)[0]; const priceDimension = Object.values(onDemandTerm.priceDimensions)[0]; return priceDimension.pricePerUnit.USD; })() : "N/A"; return { instanceId: instance.InstanceId, instanceType: instance.InstanceType, os, hourlyPrice: unitPrice }; })); };
注意事项
- Pricing API返回的
PriceList元素是JSON字符串,必须用JSON.parse()解析后才能读取属性 - 除核心字段外,
tenancy(租户)、preInstalledSw(预装软件)、capacitystatus(容量状态)等属性也会影响价格,需根据EC2实例的实际配置调整过滤条件 - 若匹配预留实例,还需额外匹配
leaseContractLength(租期)和purchaseOption(购买选项,如全预付、部分预付)
内容的提问来源于stack exchange,提问作者aab
相关产品推荐
相关产品推荐

