分解された基板とチップの部品群
技術解説

クラウド破産の入口: タグ未設定と月末アラートの落とし穴

目次を見る

AWS や Azure で毎月の請求額が読めず、気づけば前月比で数十万円増えていた。こうした経験がある基盤担当者に向けて、クラウドコストが静かに膨張する仕組みと、その手前で止める方法を整理します。

SRE やプラットフォームチームは可用性設計に注力しがちですが、コストのガバナンス不足はある日突然、予算部門からの厳しい問い合わせという形で表面化します。落とし穴の正体と、防ぐための具体的な設定を順に見ていきます。

何が起きるか: 見えないところで積み上がる無駄

クラウドの怖さは、誰も悪意なく無駄なリソースを作れてしまう点にあります。

設定ファイルを1行変更しただけで、不要に大きいメモリのクラスタが立ち上がることがあります。

典型的な無駄には次のようなパターンがあります。

  • デタッチ済みで誰も使っていないストレージボリューム
  • 実際の負荷に対して過大なサイズのワーカーノード
  • 検証用のはずが24時間稼働し続ける非本番環境
  • テスト後に削除されず放置されたリソース群

これらは1つ1つは小さくても、開発チームの数やデプロイ頻度が上がるほど掛け算で効いてきます。

月次のスプレッドシート棚卸しでは、開発速度の速いチームの変化に追いつけません。

手動確認から自動ガードレールへ移行することで、継続的なクラウド支出を15%から20%以上削減できるという報告もあります。

なぜ起きるか: 原因を段階的に分解する

1つ目の原因は、コストの帰属先が曖昧なことです。

どのチーム・どの環境・どのコストセンターが使っているリソースなのか、タグ(リソースに付与するメタデータのラベル)が付いていなければ最適化のしようがありません。

請求が締まったあとにタグを後付けしようとしても、担当者が異動していたり、リソース自体が既に削除されていたりして特定が難しくなります。

2つ目の原因は、予算超過の通知が「アラート止まり」になっていることです。

予算アラートメールは、Slack やメールの受信箱でノイズ化しやすく、開発者が忙しいと読み飛ばされます。

読まれなかった通知は、実質的に何も防いでいないのと同じです。

3つ目の原因は、コストチェックが本番デプロイの「後」に行われていることです。

Infrastructure as Code(IaC、Terraform や Pulumi のようにインフラ構成をコードで管理する仕組み)のプルリクエストの段階でコスト差分を見ずに、実際にクラウド上へリソースが作られてから気づくと、その時点で既にコストは発生しています。

これは可用性設計で言う「本番でエラーを検知してから直す」のと同じ後手対応であり、SLO(サービスレベル目標)運用で忌避されるアプローチと構造がよく似ています。

自分のプロジェクトが該当するか確認する

次の観点で、自社の環境がこの落とし穴に該当するか確認できます。

タグ強制の有無は、AWS であれば Service Control Policies(SCP、組織単位でAPI呼び出しを制御する仕組み)の一覧を確認します。

aws organizations list-policies --filter SERVICE_CONTROL_POLICY

このコマンドで返ってくるポリシー群に、RequestTag を条件とした Deny 文が含まれていなければ、タグなしでのリソース作成が野放しになっている状態です。

Azure の場合は Azure Policy の割り当て状況を Azure Portal の「ポリシー」→「割り当て」から確認するか、以下で一覧できます。

az policy assignment list --query "[].displayName"

予算の運用形態については、AWS Budgets や Azure Cost Management で設定されているアクションが「通知のみ」か「自動アクション付き」かを見ます。

AWS Budgets の画面で「アクション」タブが空欄であれば、超過時に何も自動実行されていない状態です。

CI/CD でのコストチェックは、Terraform を使っているリポジトリの .github/workflows 配下に Infracost(IaCのコスト差分を計算するツール)関連のジョブがあるかを grep します。

grep -rl "infracost" .github/workflows/

該当ファイルがなければ、プルリクエストの時点でコスト影響を確認する仕組みが存在しません。

対策の手順

手順1: タグをデプロイ時点で強制する

AWS の SCP で、CostCenter タグがないリソース作成を拒否する設定例です。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "EnforceRequiredCostCenterTag",
      "Effect": "Deny",
      "Action": ["ec2:RunInstances", "rds:CreateDBInstance"],
      "Resource": "*",
      "Condition": {
        "Null": {"aws:RequestTag/CostCenter": "true"}
      }
    }
  ]
}

このポリシーを組織のルートまたは対象OU(組織単位)にアタッチすると、CostCenter タグを付けない RunInstancesCreateDBInstance の呼び出しがIAMロールの権限に関わらず拒否されます。

Azure では同等の制御を Azure Policy の deny 効果で実装できます。

手順2: 非本番環境にハード予算上限を設ける

開発・サンドボックス・ステージング環境では、通知だけでなく実際にプロビジョニングを止める仕組みを組みます。

予算超過をトリガーに Lambda(イベント駆動で処理を実行する AWS のサーバーレス機能)を起動し、IAM の Permissions Boundary(ロールが持てる権限の上限を定義する仕組み)を適用します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "RestrictProvisioningOnBudgetExceeded",
      "Effect": "Deny",
      "Action": ["ec2:RunInstances", "rds:CreateDBInstance", "eks:CreateCluster", "redshift:CreateCluster"],
      "Resource": "*"
    }
  ]
}

この境界が適用されると、既存の無駄なリソースを削除するか請求サイクルがリセットされるまで、新規プロビジョニングが止まります。

開発者にとっては痛みを伴いますが、これがなければ放置リソースは無期限に稼働し続けます。

手順3: CI/CD にコストチェックを組み込む

GitHub Actions で Terraform 差分のコスト影響をプルリクエスト時点に検知する設定です。

name: FinOps CI Guardrail
on: [pull_request]
jobs:
  cost-estimate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: infracost/actions/setup@v3
        with:
          api-key: ${{ secrets.INFRACOST_API_KEY }}
      - name: Calculate Terraform Cost Delta
        run: |
          infracost diff --path=terraform/ --format=json --out-file=infracost.json
      - name: Enforce Spending Threshold
        run: |
          diff=$(jq '.diffTotalMonthlyCost | tonumber' infracost.json)
          if (( $(echo "$diff > 500" | bc -l) )); then
            echo "Cost increase (\$${diff}/mo) exceeds policy limit (\$500/mo). Architecture approval required."
            exit 1
          fi

注意点が2つあります。

1つ目は、コマンドを infracost breakdown ではなく infracost diff にすることです。

breakdown はある時点でのコストのスナップショットしか出さず、diffTotalMonthlyCost フィールドが存在しません。

2つ目は、bash のメッセージ内でドル記号をエスケープする際に \$ を使うことです。

$$ と書くとシェルのプロセスIDに展開されてしまい、意図した金額表示になりません。

この2点は実際にパイプラインを組む際につまずきやすい箇所なので、コピーする際は注意してください。

確認と対策のまとめ

クラウドコストの膨張は、可用性の問題と同じく「事後対応」から「事前ガードレール」へ発想を切り替えることで防げます。

次の3点は、今の環境で確認できる具体的な一歩です。

  • aws organizations list-policiesaz policy assignment list でタグ強制の有無を確認する
  • AWS Budgets のアクション設定が「通知のみ」か「自動アクション付き」か確認する
  • .github/workflows に Infracost などのコストチェックジョブがあるか grep する

どれも数分で確認できる作業です。

タグ強制・ハード予算・CI/CD でのコスト差分チェックの3点は、SLO運用で言う「事前に壊れる兆候を検知する」考え方とほぼ同じ構造を持っています。

可用性設計に投資してきたチームであれば、同じ発想をコスト管理に転用することにそれほど大きな障壁はないはずです。

参考

Killing Cloud Waste: Automating FinOps, Anomaly Detection, and Budget Enforcement

この記事について: 本記事は AI を活用して作成し、forva AI 編集部が内容を確認・監修しています。

AI 駆動開発のご相談は forva AI へ。まずはお気軽にどうぞ。