AWS SDK for Python (Boto3) の Price List API を使って EC2 の料金を取得する Python スクリプトを書きました。実行すると以下のように表示されます。
$ AWS_PROFILE=GetPrice python get_price.py --usdjpy 156.0
m8a.xlarge @ oregon usd/h= 0.243440 jpy/h= 37.98 (usdjpy=156.0)
m5zn.6xlarge @ oregon usd/h= 1.982000 jpy/h= 309.19 (usdjpy=156.0)
g6e.2xlarge @ oregon usd/h= 2.242080 jpy/h= 349.76 (usdjpy=156.0)
r6idn.8xlarge @ tokyo usd/h= 3.800160 jpy/h= 592.82 (usdjpy=156.0)
g6e.2xlarge @ tokyo usd/h= 3.251680 jpy/h= 507.26 (usdjpy=156.0)
参考文献
- Pricing - Boto3 1.42.57 documentation
- AWS Billing and Cost Management endpoints and quotas - AWS General Reference - Price List API のエンドポイントはバージニア北部、ムンバイ、フランクフルトにある。
Python スクリプト
対象リージョンやインスタンスタイプを変更するには targets を変更ください。Linux インスタンスのオンデマンド料金を取得するものになっているので適宜変更ください。
get_price.py
import argparse
import json
import sys
import time
import boto3
class PriceGetter:
location_map = {
'oregon': 'US West (Oregon)',
'tokyo': 'Asia Pacific (Tokyo)',
}
def __init__(self):
# Pricing API を使用 (リージョンはバージニア北部を指定しておくのが無難)
self.pricing = boto3.client('pricing', region_name='us-east-1')
def get_usd_per_hour(self, region, instance_type):
time.sleep(0.5)
location = PriceGetter.location_map[region]
resp = self.pricing.get_products(
ServiceCode='AmazonEC2',
Filters=[
{'Type': 'TERM_MATCH', 'Field': 'location', 'Value': location},
{'Type': 'TERM_MATCH', 'Field': 'instanceType', 'Value': instance_type},
{'Type': 'TERM_MATCH', 'Field': 'operatingSystem', 'Value': 'Linux'},
# ハードウェアを他アカウントと共有する通常インスタンス (Dedicated, Host 除外)
{'Type': 'TERM_MATCH', 'Field': 'tenancy', 'Value': 'Shared'},
# ソフトウェアがプリインストールされていないもの
{'Type': 'TERM_MATCH', 'Field': 'preInstalledSw', 'Value': 'NA'},
# 通常のオンデマンド起動用の料金 (Reserved のキャパシティ確保用などを除外)
{'Type': 'TERM_MATCH', 'Field': 'capacitystatus', 'Value': 'Used'},
],
MaxResults=1,
)
if not resp.get('PriceList'):
raise RuntimeError('No price found (filters may be too strict).')
data = json.loads(resp['PriceList'][0])
terms = data['terms']['OnDemand']
term = next(iter(terms.values()))
dim = next(iter(term['priceDimensions'].values()))
return dim['pricePerUnit']['USD']
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--usdjpy', type=float, default=155.0)
args = parser.parse_args()
pg = PriceGetter()
targets = [
('oregon', 'm8a.xlarge'),
('oregon', 'm5zn.6xlarge'),
('oregon', 'g6e.2xlarge'),
('tokyo', 'r6idn.8xlarge'),
('tokyo', 'g6e.2xlarge'),
]
for region, instance_type in targets:
usd_str = pg.get_usd_per_hour(region, instance_type)
usd = float(usd_str)
jpy = usd * args.usdjpy
print(
f'{instance_type:<16} @ {region:<8}'
f' usd/h={usd:9.6f} jpy/h={jpy:7.2f} (usdjpy={args.usdjpy})'
)
if __name__ == '__main__':
try:
raise SystemExit(main())
except Exception as e:
print(f'error: {e}', file=sys.stderr)
raise SystemExit(1)
Python スクリプトを実行する方法
上記のスクリプトは料金を取得するため、アクション pricing:GetProducts が許可されている主体でなければ実行できません。許可を得るには例えば以下の方法があります。
| 方法 | 状況 |
|---|---|
| 1. IAM ロールを EC2 にアタッチ | EC2 で実行したい |
| 2. 許可セットを IAM Identity Center ユーザに割り当て | ローカル PC で実行したい |
方法1. IAM ロールをアタッチした EC2 インスタンスで実行する
- pricing:GetProducts を含む IAM ポリシーを作成する。
- IAM → ポリシーから「ポリシーの作成」をクリックし、JSON を選択してエディタに
{"Version": "2012-10-17", "Statement": [{"Effect": "Allow", "Action": "pricing:GetProducts", "Resource": "*"}]}を記入し、適当な名前で保存する。
- IAM → ポリシーから「ポリシーの作成」をクリックし、JSON を選択してエディタに
- 1. の IAM ポリシーを含む IAM ロール (EC2 インスタンス向け) を作成する。
- IAM → ロールから「ロールの作成」をクリックし、「信頼されたエンティティタイプ」は「AWS のサービス」にチェックして下部の「サービスまたはユースケース」から「EC2」を選択し、「許可ポリシー」で 1. で作成したポリシーを選択し、適当な名前で保存する。
- 2. の IAM ロールを対象の EC2 インスタンスにアタッチする。
- その EC2 インスタンス上で
python get_price.pyを実行する。
方法2. 許可セットを割り当てた IAM Identity Center ユーザで実行する
ローカルマシンに AWS CLI がなければ先に入れてください。Windows であれば winget install -e --id Amazon.AWSCLI でインストールできます (シェルは Git Bash でも PowerShell でもコマンドプロンプトでもよいですがインストール後に開き直して aws --version が通ることを確認ください)。
- (IAM Identity Center ユーザーがなければ) IAM Identity Center でユーザーを作成する。
- IAM Identity Center ユーザーに pricing:GetProducts を含む許可セットをアサインする。
- IAM Identity Center → 許可セット → 許可セットの作成で「カスタム許可セット」を選択、インラインポリシーに
{"Version": "2012-10-17", "Statement": [{"Effect": "Allow", "Action": "pricing:GetProducts", "Resource": "*"}]}を貼り付け、適当な名前を付けて保存する。 - IAM Identity Center → AWS アカウントを開き、アカウントの一覧から対象のアカウントを選択し、「ユーザーまたはグループを割り当て」をクリックし、作成したユーザーを選択し、作成した許可セットを選択して「送信」する。
- IAM Identity Center → 許可セット → 許可セットの作成で「カスタム許可セット」を選択、インラインポリシーに
- そのユーザーとしてログインしアクセスポータル画面で 2. の許可セット名がアサインされていることを確認する。また、許可セット名の横の「アクセスキー」をクリックして開くモーダルから「SSO の開始 URL」「SSO リージョン」がコピーできるようにしておく。
-
aws configure ssoでローカルマシンにプロファイルを設定する。- 開始 URL とリージョンは 3. で確認したものをコピペする。
- ブラウザが開いてログイン画面が出るのでログインする。
- その後色々訊かれるが規定値でよい。
- 最後に訊かれる Profile name は例えば GetPrice にする (識別できればよい)。
-
aws sso login --profile GetPriceでそのプロファイルにログインする。 -
AWS_PROFILE=GetPrice python get_price.pyを実行する。