【実務・中級編】CloudFormationスタックのコスト見積もり自動化:AWS Cost ExplorerとCloudFormation Guardを連携したプロアクティブな予算超過防止策 – インフラ構成管理(IaC)活用バイブル

プロアクティブ・ガバナンスの極意:CloudFormation GuardとCost Explorerで実現する「デプロイ前コスト予測」の自動化

テックリードの私たちが日々直面する最大の悪夢は何か?
それは、夜中に突然鳴り響くアラートではない。月末に送られてくるAWSからの「想像の3倍に膨れ上がった請求書」だ。

「誰だ、検証環境に`db.r6g.16xlarge`のMulti-AZインスタンスを放置したのは!」
「えっ、NATゲートウェイのデータ転送量が想定外に……」

事後対応(Reactive)としてのAWS BudgetsやAnomaly Detectionは重要だが、これらは「財布から血が流れ出た後に止める止血帯」に過ぎない。私たちが真に求めるべきは、コードの段階(Commit/PR)でコスト影響を検知し、バジェットを超過するインフラストラクチャのデプロイを物理的に阻止するプロアクティブ・ガバナンス(Proactive Governance)だ。

今回は、AWS CloudFormation GuardとAWS Cost Explorer(Pricing API)を組み合わせ、CI/CDパイプライン上で「スタックのコストを事前に予測・検証する」ための極限の自動化手法を伝授する。

—

1. なぜ「デプロイ前のコスト予測」がSREの急務なのか?

従来のIaC(Infrastructure as Code)レビューは、セキュリティ(IAM権限の広範さ、S3の公開設定)や構文エラー(Cfn-lint)が中心だった。しかし、モダンなクラウドインフラにおいて、「コストは最大の非機能要件」である。

事後対策の限界

  • AWS Budgets / SNS通知: 予算超過後に通知されても、すでにリソースは稼働しており、停止・削除の判断コストが発生する。
  • AWS Trusted Advisor: デプロイ後の最適化提案であり、プロビジョニングそのものは防げない。

プロアクティブ検証の思想

「インフラストラクチャの変更が、組織の月額バジェットに与えるインパクトをプルリクエストの段階で数値化する」。
これをCI/CDに組み込むことで、開発チームはコードを書く段階からコスト意識を持つようになる。これを実現するのが、CloudFormation Guard(cfn-guard)によるカスタムポリシー検証と、Pythonスクリプトによるコスト算出の融合だ。

—

2. アーキテクチャの全体像

私たちが構築するパイプラインの流れは以下の通りだ。

1. Pull Request作成: 開発者がCloudFormationテンプレート(YAML/JSON)をコミット。
2. 静的解析 & コスト試算 (CI/CD):

  • `cfn-guard`で組織のコストポリシー(例: 「本番以外で高額インスタンスタイプを禁止」「プロビジョニングされるリソースの推定月額費用を算出」)を検証。
  • Pythonスクリプトがテンプレートをパースし、AWS Pricing API / Cost Explorerの過去実績データと突合して「推定月額コスト(Estimated Monthly Cost)」を算出。

3. Gate判定: 許容予算を超過している場合、あるいはポリシーに違反している場合はCIを失敗させ、PRをマージ不可にする。

—

3. 現場で使える!実用的な設定・ツールチェーン

開発スピードを落とさずにこの仕組みを導入するため、私のチームで標準化しているツールチェーンと設定を公開する。

VSCode 必須プラグイン(開発スピードの極限加速)

  • AWS CloudFormation Linter (aws-cfn-lint): 構文とリソースプロパティの妥当性をリアルタイム検証。
  • cfn-guard VSCode Extension: 後述するカスタムポリシーの違反箇所をコーディング中にエディタ上で赤波線表示させる。
  • YAML / Python: 言わずもがなの必須拡張機能。

チーム開発のための共有設定 (`.vscode/settings.json`)

リポジトリごとに以下を配置し、メンバー全員のLint・Guardルールを統一する。

{
“editor.formatOnSave”: true,
“yaml.schemas”: {
“https://raw.githubusercontent.com/awslabs/cfn-python-lint/main/v2/cfnlint/data/ServerlessTransform.json”: “template.yaml”
},
“files.associations”: {
“.guard”: “plaintext”
}
}

—

4. 実装:CloudFormation Guardによるコストポリシー定義

まずは、`cfn-guard`を用いて「コスト効率の悪いリソース構成」を弾くポリシーを定義する。
例えば、「検証環境(Environmentタグが `dev`)において、インスタンスタイプに `t3.micro` または `t3.small` 以外を使用することを禁止する」というルールをコード化しよう。

ポリシーファイル: `cost_control_policy.guard`

=====================================================================
Rule: Prevent expensive instance types in Development environments
=====================================================================

let ec2_instances = Resources.[ Type == ‘AWS::EC2::Instance’ ]

rule validate_dev_instance_cost when %ec2_instances !empty {
%ec2_instances {
# Tagsに Environment=dev が含まれているかチェック
Properties.Tags.[ Key == ‘Environment’ and Value == ‘dev’ ] exists

# インスタンスタイプが許容リストに含まれているか
Properties.InstanceType in [‘t3.micro’, ‘t3.small’, ‘t4g.micro’, ‘t4g.small’]
<< Violation: Cost Optimization Policy. Development environments must use low-cost instance types (t3.micro/small, t4g.micro/small) to prevent budget overruns. >>
}
}

このガードルールにより、開発環境にうっかり`c6i.32xlarge`などを定義したテンプレートを混入させると、ビルドパイプラインが即座にエラーを吐いて停止する。

—

5. 実装:コスト試算自動化 Pythonスクリプト

次に、CloudFormationテンプレートを解析し、AWS Pricing APIを叩いて推定コストを算出するCI用スクリプトの実装例だ。
(※簡略化のため主要なEC2インスタンスとRDSを対象とするが、拡張してS3やNAT Gatewayの従量課金も網羅可能)

`cost_estimator.py`

!/usr/bin/env python3
“””
CloudFormation Cost Estimator
テンプレート内のリソースをパースし、AWS Pricing APIを用いて月額概算コストを算出し、
指定予算と比較して超過している場合に非ゼロ終了コードを返す。
“””

import sys
import yaml
import boto3
from botocore.exceptions import ClientError

許容される最大の月額増加コスト(USD)
MAX_ALLOWED_MONTHLY_COST = 50.0

簡易的なインスタンスタイプ単価マッピング(本来はAWS Pricing API動社取得がベスト)
us-east-1の月額概算コスト(730時間計算)
PRICE_TABLE = {
‘t3.micro’: 8.76,
‘t3.small’: 17.52,
‘t3.medium’: 35.04,
‘t4g.micro’: 3.79,
‘t4g.small’: 7.59,
‘db.t3.micro’: 12.41,
‘db.t3.small’: 24.82,
}

def parse_cfn_template(file_path):
“””CloudFormationテンプレート(YAML)をロードする”””
try:
with open(file_path, ‘r’, encoding=’utf-8′) as f:
return yaml.safe_load(f)
except Exception as e:
print(f”Error parsing template: {e}”)
sys.exit(1)

def estimate_cost(template):
“””テンプレート内のリソースからコストを合算する”””
resources = template.get(‘Resources’, {})
total_monthly_cost = 0.0

print(“— Cost Estimation Report —“)
for res_name, res_def in resources.items():
res_type = res_def.get(‘Type’)
props = res_def.get(‘Properties’, {})

monthly_cost = 0.0
if res_type == ‘AWS::EC2::Instance’:
inst_type = props.get(‘InstanceType’, ‘t3.micro’)
monthly_cost = PRICE_TABLE.get(inst_type, 50.0) # 未知の型は保守的に高めに見積もる
print(f”[EC2] {res_name} ({inst_type}): ${monthly_cost:.2f} / month”)

elif res_type == ‘AWS::RDS::DBInstance’:
inst_type = props.get(‘DBInstanceClass’, ‘db.t3.micro’)
monthly_cost = PRICE_TABLE.get(inst_type, 100.0)
print(f”[RDS] {res_name} ({inst_type}): ${monthly_cost:.2f} / month”)

total_monthly_cost += monthly_cost

print(f”——————————“)
print(f”Total Estimated Monthly Cost: ${total_monthly_cost:.2f}”)
return total_monthly_cost

def main():
if len(sys.argv) < 2: print("Usage: python cost_estimator.py “)
sys.exit(1)

template_path = sys.argv[1]
template = parse_cfn_template(template_path)
estimated_cost = estimate_cost(template)

if estimated_cost > MAX_ALLOWED_MONTHLY_COST:
print(f”\n[ERROR] Cost Policy Violation: Estimated cost (${estimated_cost:.2f}) exceeds the maximum allowed limit (${MAX_ALLOWED_MONTHLY_COST:.2f}).”)
sys.exit(1)
else:
print(“\n[SUCCESS] Cost check passed within budget.”)
sys.exit(0)

if __name__ == ‘__main__’:
main()

—

6. CI/CDパイプラインへの統合(GitHub Actions)

最後に、これまで作成した`cfn-guard`と`cost_estimator.py`をGitHub Actionsのワークフローに組み込む。プルリクエストが作成・更新された瞬間に、これらのガードレールが自動的に発動するように設定する。

`.github/workflows/cost-governance.yml`

name: Proactive Cost Governance

on:
pull_request:
branches:

  • main

paths:

  • ‘cloudformation//.yaml’
  • ‘cloudformation//.yml’

jobs:
cost-and-policy-check:
runs-on: ubuntu-latest
steps:

  • name: Checkout Repository

uses: actions/checkout@v4

  • name: Set up Python

uses: actions/setup-python@v5
with:
python-version: ‘3.10’

  • name: Install Dependencies

run: |
python -m pip install –upgrade pip
pip install pyyaml boto3

  • name: Setup AWS CloudFormation Guard

run: |
# 最新の cfn-guard バイナリをダウンロードしてインストール
curl –proto ‘=https’ –tlsv1.2 -sSf https://raw.githubusercontent.com/aws-cloudformation/cloudformation-guard/main/install-guard.sh | sh
echo “$HOME/.cargo/bin” >> $GITHUB_PATH

  • name: Run CloudFormation Guard Policy Check

run: |
# 組織のコストポリシーに照らし合わせて検証
cfn-guard validate \
–data cloudformation/template.yaml \
–rules policies/cost_control_policy.guard

  • name: Run Automated Cost Estimation Script

env:
AWS_DEFAULT_REGION: us-east-1
# 必要に応じてAWSの認証情報を設定(Pricing APIなどを叩く場合)
run: |
python scripts/cost_estimator.py cloudformation/template.yaml

—

7. 伝説のテックリードからのメッセージ

インフラの自動化において、コードを「素早くデプロイすること」だけがエンジニアの成果ではない。「組織のビジネスインパクト(コスト)をコードの段階でコントロールし、予測不可能な無駄を排除すること」こそが、SREおよびインフラエンジニアの真骨頂である。

今回紹介した CloudFormation Guard とコスト試算スクリプトの連携は、あなたのチームに以下の変革をもたらす:
1. 心理的安全性の向上: 「うっかり高額リソースをデプロイしてしまうかもしれない」という恐怖から開発者を解放する。
2. 手戻りの削減: レビューの段階でコスト面の議論が完了するため、後からのリファクタリング工数がゼロになる。
3. FinOps文化の定着: インフラコードを書くことイコール「コストを設計すること」というマインドセットがチーム全体に浸透する。

さあ、今すぐリポジトリに `cost_control_policy.guard` を配置し、月末の恐怖から解放されたモダンなインフラ開発フローを手に入れよう。

タイトルとURLをコピーしました