AWSのコスト計算
AWSのコストを予測したいと思って調査
AWS公式ツールの存在
AWS Cost Explorer
過去の料金実績から今後を予想
運用中のサービスがイベントをするので、コスト予測したいには使えるが、明日から本番運用なので、コスト見積もり出したいってニーズには合わない。
AWS Pricing Calculator
Billing and Cost Management > 料金見積もりツール
https://calculator.aws/#/
- 1ヶ月=730時間(365日×24時間÷12ヶ月)」を前提として計算
https://aws.amazon.com/jp/calculator/calculator-faq/ - 利用者数を直接指定できない
自動監視したいならAPI利用
AWS Price List Query API
リアルタイムの料金情報(1時間XX円など)を取得できる
# EC2のt3.xlargeインスタンスのLinux料金を取得する例
#--regionには、us-east-1、eu-central-1、ap-south-1のいずれかのみ(APIエンドポイントがあるのは3リージョンのみで、料金自体は全リージョン取得可能)
aws pricing get-products --service-code AmazonEC2 --region us-east-1 --filters \
Type=TERM_MATCH,Field=regionCode,Value="ap-northeast-1" \
Type=TERM_MATCH,Field=instanceType,Value="t3.xlarge" \
Type=TERM_MATCH,Field=operatingSystem,Value="Linux" \
Type=TERM_MATCH,Field=tenancy,Value="Shared" \
Type=TERM_MATCH,Field=marketoption,Value="OnDemand"
JSONでレスポンスがくる
{
"terms": {
"OnDemand": {
"4YN89ZSXY92DK7Q8.JRTCKXETXF": {
"priceDimensions": {
"4YN89ZSXY92DK7Q8.JRTCKXETXF.6YS6EN2CT7": {
"unit": "Hrs", // 1時間当たりの金額
"pricePerUnit": {
"USD": "0.7712000000"
}
}
}
}
}
}
}
pythonでの実装例(みんな大好きboto3)
import boto3
import json
from decimal import Decimal
def get_aws_pricing(service_code, filters):
# 注意: Pricing APIは特定のリージョンでのみ利用可能
pricing_client = boto3.client('pricing', region_name='us-east-1')
response = pricing_client.get_products(
ServiceCode=service_code,
Filters=filters
)
return response
# 使用例:东京リージョンのt3.mediumインスタンス料金を取得
filters = [
{'Type': 'TERM_MATCH', 'Field': 'regionCode', 'Value': 'ap-northeast-1'},
{'Type': 'TERM_MATCH', 'Field': 'instanceType', 'Value': 't3.medium'},
{'Type': 'TERM_MATCH', 'Field': 'operatingSystem', 'Value': 'Linux'},
{'Type': 'TERM_MATCH', 'Field': 'tenancy', 'Value': 'Shared'},
{'Type': 'TERM_MATCH', 'Field': 'marketoption', 'Value': 'OnDemand'}
]
pricing_data = get_aws_pricing('AmazonEC2', filters)
より詳細な情報は以下リンク先
https://blog.serverworks.co.jp/Price_List_Query_API
Cost Explorer API
実績データ(自分のアカウントの実際の利用料金や予測コスト)を取得できる
import boto3
from datetime import datetime, timedelta
def get_cost_forecast():
ce_client = boto3.client('ce', region_name='us-east-1')
# 月末までのコスト予測を取得
response = ce_client.get_cost_forecast(
TimePeriod={
'Start': (datetime.now() + timedelta(days=1)).strftime('%Y-%m-%d'),
'End': (datetime.now().replace(day=1) + timedelta(days=32)).replace(day=1).strftime('%Y-%m-%d')
},
Metric='UNBLENDED_COST',
Granularity='MONTHLY'
)
return response
参考リンク先
https://tryt-group.hatenablog.com/entry/2022/12/20/183426
為替レートAPI($→¥変換)
Open Exchange Ratesに決めた。
実績と月1000回も使わないので。
毎時更新だけど、そこまで大幅に変わらないだろうし、24時間キャッシュとかでもいいかも。
APIキーは、Secret Managerに登録(サンプルコードは直接指定になっている)
### exchangerate.host
- 完全無料で制限なし
- 更新頻度は日次(1日1回)
- 無料プランではリアルタイムレートは非対応
Open Exchange Rates
- 無料プランは月1000リクエスト、毎時更新
- 信頼性の高い為替レートAPI(様々な企業で利用実績あり)
import requests
def get_exchange_rate():
# 無料プランは1,000回/月まで
app_id = "YOUR_APP_ID"
url = f"https://openexchangerates.org/api/latest.json?app_id={app_id}"
response = requests.get(url)
data = response.json()
# USDからJPYへのレート
jpy_rate = data['rates']['JPY']
return jpy_rate
キャッシュ戦略
24時間はキャッシュを利用する
定期実行
lambda + EventBridge
通知
SNSで通知、または、Slack Webhook
エラーハンドリング
外部APIに依存するアプリなので注意
リトライロジックを入れる
利用中のAWSリソース取得
boto3.client('config')などで取得
計算
- 定額のもの
- 時間課金のもの
- 通信料課金(外部インターネットから無料、同一AZ無料)