EC2コスト削減の実践ガイド:リザーブドインスタンスとSavings Plansを使い分ける
この記事でわかること
- EC2の料金体系(オンデマンド・RI・Savings Plans)の違いと使い分け
- Compute Optimizer を使ったリサイジング推奨の読み方
- EventBridge Scheduler + Lambda でEC2の自動起動・停止を実装する方法
- 実際にどれくらいコスト削減できるかの試算方法
実務での背景
AWSの請求書を眺めていると「EC2だけでこんなにかかってるの?」と驚くことがあります。特に開発環境や検証環境では、夜間・休日もEC2が動き続けているケースが非常に多いです。
また、本番環境では適切なコミットメントディスカウント(RI・Savings Plans)を使っていないために、オンデマンド料金をそのまま払い続けているケースも多く見受けられます。
本記事では「今日から使える」コスト削減の実践的な手順を解説します。
解決方法
アプローチ1:開発・検証環境の自動停止
最もインパクトが大きい施策です。開発環境が24時間365日動いている場合、夜間(18時〜9時)と休日を止めるだけで約73%の削減になります。
週間稼働時間の比較:
- 現状(常時稼働): 168時間/週
- 平日 9:00〜18:00 のみ: 45時間/週
- 削減率: (168 - 45) / 168 ≈ 73%
アプローチ2:Compute Optimizerでリサイジング
過剰スペックのインスタンスをダウングレードします。t3.xlarge → t3.medium への変更で約50%削減できます。
アプローチ3:Savings PlansまたはRIの購入
安定稼働している本番環境には、コミットメントディスカウントを適用します。最大66〜72%割引になります。
具体的な手順
Step 1: Compute Optimizer で最適化推奨を確認
# Compute Optimizer の推奨を取得
aws compute-optimizer get-ec2-instance-recommendations \
--query 'instanceRecommendations[*].[instanceArn,finding,recommendationOptions[0].instanceType,recommendationOptions[0].estimatedMonthlySavings.value]' \
--output table
出力例:
----------------------------------------------------------------------
| GetEC2InstanceRecommendations |
+---------------------+------------------+----------+-------+ |
| i-0abc123def456 | OVER_PROVISIONED | t3.medium| 45.20 | |
+---------------------+------------------+----------+-------+
Step 2: Lambda 関数でEC2の起動・停止を実装
import boto3
def lambda_handler(event, context):
ec2 = boto3.client('ec2')
action = event.get('action', 'stop') # 'start' or 'stop'
# タグ AutoStop=true のインスタンスを対象とする
state_filter = 'running' if action == 'stop' else 'stopped'
response = ec2.describe_instances(
Filters=[
{'Name': 'tag:AutoStop', 'Values': ['true']},
{'Name': 'instance-state-name', 'Values': [state_filter]}
]
)
instance_ids = [
i['InstanceId']
for r in response['Reservations']
for i in r['Instances']
]
if not instance_ids:
print("対象インスタンスなし")
return {'stopped': [], 'started': []}
if action == 'stop':
ec2.stop_instances(InstanceIds=instance_ids)
print(f"停止対象: {instance_ids}")
else:
ec2.start_instances(InstanceIds=instance_ids)
print(f"起動対象: {instance_ids}")
return {action: instance_ids}
Step 3: EventBridge Scheduler でタイムゾーン指定のスケジュール設定
推奨: 従来の
aws events put-ruleではcronがUTC固定でした。EventBridge Scheduler を使うとタイムゾーンを直接指定できます。
# 平日 18:00 JST に停止(タイムゾーン直接指定)
aws scheduler create-schedule \
--name "ec2-auto-stop-weekdays" \
--schedule-expression "cron(0 18 ? * MON-FRI *)" \
--schedule-expression-timezone "Asia/Tokyo" \
--flexible-time-window Mode=OFF \
--target '{
"Arn": "arn:aws:lambda:ap-northeast-1:123456789012:function:ec2-scheduler",
"RoleArn": "arn:aws:iam::123456789012:role/EventBridgeSchedulerRole",
"Input": "{\"action\": \"stop\"}"
}'
# 平日 9:00 JST に起動
aws scheduler create-schedule \
--name "ec2-auto-start-weekdays" \
--schedule-expression "cron(0 9 ? * MON-FRI *)" \
--schedule-expression-timezone "Asia/Tokyo" \
--flexible-time-window Mode=OFF \
--target '{
"Arn": "arn:aws:lambda:ap-northeast-1:123456789012:function:ec2-scheduler",
"RoleArn": "arn:aws:iam::123456789012:role/EventBridgeSchedulerRole",
"Input": "{\"action\": \"start\"}"
}'
Step 4: Savings Plans の購入判断
# 過去1ヶ月のEC2使用状況を確認(us-east-1 固定)
aws ce get-cost-and-usage \
--time-period Start=2024-01-01,End=2024-02-01 \
--granularity DAILY \
--metrics UsageQuantity \
--group-by Type=DIMENSION,Key=INSTANCE_TYPE \
--output table \
--region us-east-1
構成図
ハマりポイント
❌ RDSを止め忘れる
EC2を止めてもRDSが動いていると意外とコストがかかります。RDSも同様にスケジュール停止できます。
# RDS停止(手動)
aws rds stop-db-instance --db-instance-identifier dev-mysql
# RDS自動停止はLambdaで実装
import boto3
def stop_rds(instance_id):
boto3.client('rds').stop_db_instance(DBInstanceIdentifier=instance_id)
注意: RDSは最大7日間しか停止状態を維持できません。7日経つと自動的に再起動します。
❌ Savings PlansとRIの違いを混同する
| 項目 | リザーブドインスタンス(RI) | Savings Plans |
|---|---|---|
| 柔軟性 | 低(特定インスタンスタイプ・リージョン固定) | 高(Compute SPはファミリー横断・リージョン問わず) |
| 割引率 | 最大72%(全額前払い) | 最大66%(Compute SP) |
| 向き | インスタンスタイプが固定の本番環境 | 変化しやすい環境・ECS Fargate・Lambda |
❌ Lambdaのタイムアウトを短くしすぎる
対象インスタンスが多い場合、Lambda関数の実行時間が伸びます。デフォルト3秒では足りないため、タイムアウトを60〜300秒に設定しましょう。
まとめ
| 施策 | 対象 | 削減率(目安) | 難易度 |
|---|---|---|---|
| 自動停止 | 開発・検証環境 | 〜73% | 低 |
| リサイジング | 過剰スペック環境 | 〜50% | 低 |
| Savings Plans | 本番環境 | 〜30〜66% | 中 |
コスト削減は「どれか1つやれば終わり」ではなく、複数の施策を重ねることで大きな効果が出ます。 まずは「開発環境の自動停止」から始めるのが最も費用対効果が高くおすすめです。
