Article

IT予算を30%削減しても品質を保つ方法

高田晃太郎
IT予算を30%削減しても品質を保つ方法

複数の調査やベンダー資料では、企業のクラウド支出のうち30〜40%が最適化余地として指摘され¹、Flexeraの年次調査でも自己申告ベースで約28%の過剰支出が報告されています²。過去の同社調査では実測に基づく過剰支出が35%に達するケースも示されています³。また、DORAのレポート群は、デプロイ頻度やMTTR(平均復旧時間)などのエンジニアリング指標がビジネス成果と相関することを指摘します⁴。公開情報と現場の一般的な知見を重ねると、予算をただ切り詰めるのではなく、測定可能な品質指標を軸にコスト構造を再設計した組織ほど、無駄が減って品質が安定しやすい傾向が見えます。ここでいう品質は感覚ではなく、サービスレベル目標(SLO)、変更失敗率、回復時間(MTTR)といった定量指標です。重要なのは、思いつきの施策を積み上げるのではなく、単位経済(1リクエスト当たりコスト)とエラーバジェット(SLOの範囲内で許容される失敗の余地)をコンパスに、投資と抑制を同じフレームで意思決定することです。

品質を測り直す:SLOと単位経済を予算の言語にする

品質を守る前提は、守るべき水準を数値で合意することです。稼働率の百分率と現場の体感が混ざると、どこまでならコストを絞れるかのラインが曖昧になります。まずはコアユーザー体験に直結するメトリクスを選び、月次ではなく四半期のエラーバジェットとして管理します。たとえば可用性99.9%を掲げるサービスの28日ウィンドウにおける許容エラー時間は約40分です。このバジェットを使い切らない限り、キャパシティ調整や構成変更を進める余地が生まれます。SLO運用の現場では、次のようなPromQLで消費ペースを常時計測して判断材料にします。

sum_over_time(rate(http_requests_total{status=~"5.."}[5m])[28d:5m])
  /
sum_over_time(rate(http_requests_total[5m])[28d:5m])

同時に、予算は機能単位ではなく単位経済で語るとブレません。ユーザー1件のリクエストやジョブ1本の処理当たりのコストを明らかにし、今期の改善でどの程度下げるかをOKR化します。例えば1,000万リクエストあたりの総クラウドコストが12万円であるなら、30%の改善目標は8万4千円です。これは部門横断の合意形成を容易にし、アーキテクチャ、運用、契約の各レイヤーからの寄与を矛盾なく足し合わせられるため、意思決定の衝突が減ります。単位経済の把握には、コストデータとプロダクトのボリュームデータを突き合わせる必要があります。AWSではCost and Usage Report(CUR)をAthenaに流し込み、サービス側の呼び出し回数やトラフィックを連結するのが実務的です⁵。以下はサービス名とリクエスト数で1リクエスト当たりコストを算出する例です。

SELECT
  s.service_name,
  SUM(cost.line_item_blended_cost) AS blended_cost_usd,
  SUM(s.request_count) AS requests,
  SUM(cost.line_item_blended_cost) / NULLIF(SUM(s.request_count), 0) AS cost_per_request
FROM cur.cost_line_items AS cost
JOIN analytics.service_requests AS s
  ON cost.usage_start_date = s.usage_start_time
  AND cost.resource_id = s.resource_id
WHERE cost.usage_start_date BETWEEN date '2025-05-01' AND date '2025-05-31'
GROUP BY s.service_name
ORDER BY cost_per_request DESC;

この数字が出れば、どのサービスが単位経済を悪化させているかが瞬時に特定でき、後述の施策の優先順位付けが合理的に進みます。ポイントは、品質の会話もコストの会話も同じ時間窓・同じ粒度で比較することです。これにより、たとえばオートスケールの下限台数を調整してもSLOの消費速度が許容範囲に収まるなら、躊躇する理由は薄くなります。

品質を落とさない即効テクニック:リソース、ストレージ、CI/CDの三点締め

短期間での支出圧縮には、資源の使い過ぎを自動で止める仕組み、データの置き場所と期限の見直し、パイプラインの無駄な計算を抑える工夫という三点を並行で回すのが効果的です。まずリソース管理では、タグやスケジュールが付かないリソースの作成そのものを止めると効果が直線的に現れます。ポリシー・アズ・コードで未タグ資産を拒否し、残存リソースを夜間停止の対象に自動分類します。タグ戦略とコスト配賦はAWSのプラクティスに沿うのが近道です⁶。OPA/Regoでのシンプルな否認例は次のとおりです。

package tf.policy

deny[msg] {
  input.resource.kind == "aws_instance"
  not input.resource.tags["cost-center"]
  msg := "cost-center タグが必須です"
}

deny[msg] {
  input.resource.kind == "aws_instance"
  not input.resource.tags["schedule"]
  msg := "schedule タグが必須です"
}

スケジュールタグに従って非稼働時間のコストを自動で刈り取るには、開発・検証環境の停止を徹底します。たとえば20時〜8時と週末の完全停止を徹底するだけで、平日8時間×5日に対して時間ベースで約65%の停止余地が生まれ、時間課金のリソースでは比例的にコストが下がりうる設計になります。次のようなスクリプトをEventBridgeやCloud Schedulerに結び、人的オペレーションを介さないことが継続の鍵です。なお、AWSは非本番環境の自動起動・停止により大幅なコスト最適化が可能であると具体例とともに解説しています⁷。

import boto3
import os

ec2 = boto3.client('ec2', region_name=os.getenv('AWS_REGION', 'ap-northeast-1'))

def stop_idle_dev_instances():
    filters = [
        {"Name": "tag:schedule", "Values": ["nightly"]},
        {"Name": "instance-state-name", "Values": ["running"]}
    ]
    resp = ec2.describe_instances(Filters=filters)
    ids = [i['InstanceId'] for r in resp['Reservations'] for i in r['Instances']]
    if ids:
        ec2.stop_instances(InstanceIds=ids)

if __name__ == "__main__":
    stop_idle_dev_instances()

ストレージは高頻度アクセスと保管の住み分けで単価を下げます。オブジェクトはアクセス頻度を観測した上で、30日無アクセスを基準にIAまたはArchiveへ自動移行するライフサイクルを設定し、スナップショットは世代管理と圧縮を組み合わせます。ここで品質が揺らぐのは復元時間だけです。SLO観点で求めるRTO(目標復旧時間)を明示し、復元時間の実測をもって階層を決定すれば、支出抑制と品質は両立します。CI/CDは見落とされがちな大口です。分散キャッシュが効かない巨大なビルドや、平行ジョブの過剰起動、使われないプレビュー環境がコストとリードタイムを同時に悪化させます。次の設定はGitHub Actionsの平行実行とプレビュー破棄を制御し、時間課金の無駄と変更失敗率の上昇を抑えます⁸。

name: ci
on: [push, pull_request]
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - uses: actions/checkout@v4
      - uses: actions/cache@v4
        with:
          path: ~/.cache/build
          key: ${{ runner.os }}-build-${{ hashFiles('**/lockfiles') }}
      - run: ./scripts/build.sh
  preview:
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    steps:
      - run: ./scripts/preview_up.sh
      - if: github.event.action == 'closed'
        run: ./scripts/preview_down.sh

これら三点を組み合わせると、未使用資産の整理も含めて短期で二桁%のコスト圧縮が狙えます。一般的な目安としては、30〜45日程度で総コストの15〜22%の削減レンジを達成しうる一方、品質指標は変更失敗率で横ばい〜小幅改善、MTTRは10〜20%短縮といった着地が期待されます。ただし数値は環境に強く依存し、参考値である点に留意してください。オブジェクトストレージの階層化やライフサイクル設計に関する実装の考え方はAWS公式のコスト最適化ガイドが参考になります⁹。

アーキテクチャと契約を整える:持続的な15%追加削減

短期の刈り取りが終わったら、構造的な最適化に進みます。まずスケールの出る経路にキャッシュと非同期化を適用し、ピーク帯の同時性と台数の積に効かせます。リードレプリカの乱立や過剰なキュー分断はコストの温床です。ホットパスはメモリキャッシュに寄せ、コールドパスはバッチ化し、遅延許容なジョブはイベント駆動に切り替えます。ここでの注意はレイテンシのSLOです。例えばp95の目標を400msから450msへわずかに緩めるだけで必要台数が二桁%下がるケースもありますが、ユーザー価値に響かないかをABで検証することが前提です。右サイズ化はメトリクス駆動で行い、CPU・メモリのp95利用率が30%未満のワークロードは一段階小さいシェイプに降ろし、HPAの下限は実績平均の80%水準に合わせると良い結果が出やすくなります。データベースはI/Oと接続数のボトルネックを中心に観測し、接続プールの上限見直しとSQLのN+1解消がスケール単価に直結します。契約面ではリザーブドインスタンスやSavings Plansのコミットを適切に用いると、ワークロード次第で大きな割引(カタログ値で最大72%)が得られますが、コミット過多は柔軟性を損ない品質を縛るリスクに転じます¹¹。ここでも単位経済が羅針盤です。過去90日のピーク下限を基準に、オンデマンドとコミットの比率を6:4から開始し、四半期ごとに見直します。コスト監視の可視化はダッシュボードに留めず、しきい値超過時にPRをブロックするなどSDLCへ組み込みます。TerraformやPulumiと組み合わせ、費用見積もりをパイプラインの段階で強制します。

# 事前見積もりに基づくブロック例(疑似)
name: cost-guard
on: pull_request
jobs:
  estimate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: infracost breakdown --path=. --format=json --out-file=out.json
      - run: python scripts/fail_if_over.py out.json 0.05  # 月次+5%超過なら失敗

最後に、ログ・メトリクス・トレースの観測コストそのものも品質を損なわずに抑制できます。重要なのは無制限の保存と集約を当然視しないことです。高価な全文検索は直近7日だけにし、以降はオブジェクトストレージへ圧縮保管して必要時に抽出します。トレースは全量ではなくヘッドベースのサンプリングとヒット率の動的制御を行い、SLO付近の期間だけサンプリングを濃くします。こうした見直しを組み合わせると、運用監視コストで二桁%の削減が報告されることもあり、アラート品質がむしろ向上するケースもあります。ログの保持期間・ポリシーは自動化してドリフトを防ぐと効果が安定します¹⁰。

90日で達成するロードマップと成果数値

実行の順番が成果を左右します。初月は可視化と止血に集中し、SLOと単位経済のダッシュボードを用意してから、未タグ資産の遮断、夜間停止の徹底、プレビュー環境の自動破棄を一気に進めます。この段階で総コストの10〜15%程度の圧縮が見込めるのが一般的な目安です。二ヶ月目はリソースの右サイズ化とストレージ階層化を並行させ、CIの平行度制御とキャッシュ最適化でビルド時間を20〜40%短縮します。ここで累計20〜27%の圧縮レンジに到達する設計が現実的です。三ヶ月目はコミット契約の導入やイベント駆動化、ホットパスのキャッシュ強化を段階的に実施し、SLOのエラーバジェット消費と相関を見ながら上限を詰めます。累計で28〜35%の削減は、前提条件が整えば到達可能なレンジとして妥当です。品質指標は、稼働率が99.9%目標に対して偏差0.1ポイント以内、変更失敗率で基線比10〜20%改善、リードタイムで15〜25%短縮といったモデルケースが想定されます。あくまで参考値であり、各社のアーキテクチャやトラフィック特性によって変動します。

参考となる実装の断片:コストの実装面ガードレール

実務では、ポリシーだけでなく運用の自動化が成果を安定させます。たとえばIaCの差分から費用の増分を見積もり、しきい値を超えたPRを自動で赤にする仕掛けを入れるだけで、レビューアの認知負荷は大きく下がります。次はInfracostの出力を検査して失敗させる例の簡素版です。

# scripts/fail_if_over.py
import json, sys
path, threshold = sys.argv[1], float(sys.argv[2])
with open(path) as f:
    data = json.load(f)
ratio = data.get('totalMonthlyCostEstimateDelta', 0.0)
if ratio > threshold:
    print(f"Cost delta {ratio:.2%} over threshold {threshold:.2%}")
    sys.exit(1)
print("Cost delta within threshold")

このようなガードレールは、品質を守るブレーキと同義です。コストを意識した変更は結果的に変更量の粒度を整え、失敗時の巻き戻しを容易にし、品質の安定に寄与します。

まとめ:数字で意思決定すれば、削減は品質の敵ではない

コスト最適化は痛みを伴う切り捨てではなく、品質を「測れる言語」に翻訳することで合意形成の速度を上げる営みです。SLOと単位経済を中核に据え、即効の三点締めと、アーキテクチャと契約の構造最適化を重ねれば、90日で二桁%のコスト圧縮と、変更失敗率・MTTR・リードタイムの改善を同時に狙えます。あなたの現場でまず試すべきは、単位経済のダッシュボードとエラーバジェットの可視化です。今日から始められる小さな一歩として、未タグ資産の拒否と夜間停止の自動化を導入し、次の四半期には契約の見直しとキャッシュ・非同期化の設計に踏み込みましょう。数字があなたの味方になり、コストも品質も同じ儀式の中で前進し始めます。次のスプリントレビューで、あなたはどの指標を示しますか。SLOの健全な残高でしょうか、それとも1リクエスト当たりコストの新しい基準値でしょうか。

参考文献

  1. Interactive: Cloud Wastage Checklist. https://www.interactive.com.au/white-papers/cloud-wasteage-checklist/
  2. Flexera: 2023 State of the Cloud Report. https://www.flexera.com/resources/research/state-of-the-cloud-report
  3. Flexera Press Release: RightScale 2019 State of the Cloud Report from Flexera Identifies Cloud Adoption Trends. https://www.flexera.com/about-us/press-center/rightscale-2019-state-of-the-cloud-report-from-flexera-identifies-cloud-adoption-trends
  4. Atlassian: DORA metrics and their benefits. https://www.atlassian.com/devops/frameworks/dora-metrics
  5. AWS Cost Management Blog: Querying your AWS Cost and Usage Report using Amazon Athena. https://aws.amazon.com/blogs/aws-cost-management/querying-your-aws-cost-and-usage-report-using-amazon-athena/
  6. AWS Prescriptive Guidance: Introduction to cost allocation and tagging. https://docs.aws.amazon.com/prescriptive-guidance/latest/cost-allocation-tagging/introduction.html
  7. AWS Architecture Blog: Optimize cost by automating the start/stop of resources in non-production environments. https://aws.amazon.com/blogs/architecture/optimize-cost-by-automating-the-start-stop-of-resources-in-non-production-environments/
  8. GitHub Docs: Control workflow concurrency. https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency
  9. AWS Storage Blog: Amazon S3 cost optimization for predictable and dynamic access patterns. https://aws.amazon.com/blogs/storage/amazon-s3-cost-optimization-for-predictable-and-dynamic-access-patterns/
  10. AWS Infrastructure & Automation Blog: Reduce log storage costs by automating retention settings in Amazon CloudWatch. https://aws.amazon.com/blogs/infrastructure-and-automation/reduce-log-storage-costs-by-automating-retention-settings-in-amazon-cloudwatch/
  11. AWS Savings Plans: Flexible pricing model offering savings up to 72%. https://aws.amazon.com/savingsplans/