DevOps Agentの月間利用時間でアラート通知してみた

DevOps Agentの月間利用時間でアラート通知してみた

2026.05.06

こんにちは。たかやまです。

以下の記事にてDevOps Agentの稼働時間をCloudWatchメトリクスとCloudWatchアラームで監視しようとしたところ、CloudWatchアラームのPeriod上限が7日のため月間累計時間でのアラート通知ができないという問題がありました。

https://dev.classmethod.jp/articles/devops-agent-vended-logs-and-metrics/

ただ、上記ブログ内でも紹介していますが、DevOps Agentは月間利用時間を返す aws devops-agent get-account-usage API があります。

$ aws devops-agent get-account-usage
{
    "monthlyAccountInvestigationHours": {
        "limit": 200,
        "usage": 2.3852777777777776
    },
    ...
    "usagePeriodStartTime": "2026-04-01T00:00:00+00:00",
    "usagePeriodEndTime":   "2026-04-25T07:59:43.918000+00:00"
}

APIで取得した usage をカスタムメトリクスに流し込めば、CloudWatchアラームで月間累計を扱えるのではないかということで、今回はこのAPIをLambdaから定期実行してCloudWatchカスタムメトリクスに発行し、月間総稼働時間でアラート通知する仕組みを実装していきたいと思います。

さきにまとめ

  • get-account-usage APIをLambdaから定期実行し、月間累計時間をCloudWatchカスタムメトリクスとして発行することで月間累計時間を監視できるようになる
    • get-account-usage はリージョンごとに異なる使用量を返すため、複数リージョンでDevOps Agentを利用している場合にはリージョンごとの監視が必要(または合算を行う)
  • カスタムメトリクスはAPI側で月初リセットされる値をそのまま発行するため、月初リセット処理は不要

クイックスタートはこちら

構成全体の月コストは約$0.5(Lambda・EventBridge Scheduler・CloudWatchメトリクスとアラーム使用)

Launch Stack

やってみる

アーキテクチャ

全体の構成は以下のとおりです。

devops-agent-usage-alert-architecture.png

get-account-usage APIの確認

まずはAPIレスポンスを確認します。

$ aws devops-agent get-account-usage

実行結果は以下のようなレスポンスになります。

{
    "monthlyAccountInvestigationHours": {
        "limit": 400,
        "usage": 0.0
    },
    "monthlyAccountEvaluationHours": {
        "limit": 300,
        "usage": 0.14444444444444443
    },
    "monthlyAccountSystemLearningHours": {
        "limit": 80,
        "usage": 0.0
    },
    "usagePeriodStartTime": "2026-04-01T00:00:00+00:00",
    "usagePeriodEndTime":   "2026-04-25T07:59:43.918000+00:00"
}
フィールド 説明
monthlyAccountInvestigationHours.usage 月間累計の調査時間(時間単位)
monthlyAccountInvestigationHours.limit 調査時間の月間上限(時間単位)
monthlyAccountEvaluationHours.usage 月間累計の評価時間(時間単位)
monthlyAccountEvaluationHours.limit 評価時間の月間上限(時間単位)
monthlyAccountSystemLearningHours.usage 月間累計のシステム学習時間(時間単位)
monthlyAccountSystemLearningHours.limit システム学習時間の月間上限(時間単位)
usagePeriodStartTime 集計期間の開始(月初)
usagePeriodEndTime 集計期間の終了(取得時点)

参照 : get-account-usage - AWS CLI Command Reference

なお、公式ドキュメント上は "monthly account usage metrics" と記載されていますが、実際に複数リージョンで get-account-usage を叩いて確認したところ、リージョンごとに異なる使用量が返ってきました。

$ aws devops-agent get-account-usage --region us-east-1
{
    "monthlyAccountInvestigationHours": {
        "limit": 400,
        "usage": 0.0
    },
    "monthlyAccountEvaluationHours": {
        "limit": 300,
        "usage": 0.14444444444444443
    },
    "monthlyAccountSystemLearningHours": {
        "limit": 80,
        "usage": 0.0
    },
    "usagePeriodStartTime": "2026-05-01T00:00:00+00:00",
    "usagePeriodEndTime": "2026-05-03T03:45:38.910000+00:00"
}

$ aws devops-agent get-account-usage --region ap-northeast-1
{
    "monthlyAccountInvestigationHours": {
        "limit": 400,
        "usage": 0.0
    },
    "monthlyAccountEvaluationHours": {
        "limit": 300,
        "usage": 0.0
    },
    "monthlyAccountSystemLearningHours": {
        "limit": 80,
        "usage": 0.0
    },
    "usagePeriodStartTime": "2026-05-01T00:00:00+00:00",
    "usagePeriodEndTime": "2026-05-03T03:51:14.797000+00:00"
}

us-east-1 では 「monthlyAccountEvaluationHours.usage」 が 0.144 時間返っているのに対し、ap-northeast-1 では 「monthlyAccountEvaluationHours.usage」 が 0.0 時間と、リージョンによって異なる値になっています。

そのため、複数リージョンでDevOps Agentを利用している場合にはリージョンごとに使用量を監視するか、またはリージョンごとの使用量を合算して監視する必要がありそうです。

こちらの記事ではリージョンごとの使用量を監視する形で実装しています。

Lambda関数の実装

今回実装のメインになるLambda関数はこちらです。

DevOps Agent APIはLambda同梱boto3にまだ未対応のため、boto3.client("devops-agent") ではなく、urllib と SigV4署名でAPIエンドポイントを直接呼び出しています。

Lambda Layerでboto3最新版を持ち込む方法もありますが、今回はAPIを直接呼び出すことで、Layer不要のシンプルな構成にしています。

import json
import os
import urllib.request

import boto3
from botocore.auth import SigV4Auth
from botocore.awsrequest import AWSRequest

NAMESPACE = "Custom/DevOpsAgent"
METRIC_NAME = "MonthlyInvestigationHours"
REGION = os.environ["AWS_REGION"]
ENDPOINT = f"https://dp.aidevops.{REGION}.api.aws/usage/account"

session = boto3.Session()
cloudwatch = session.client("cloudwatch", region_name=REGION)

def get_account_usage():
    request = AWSRequest(method="GET", url=ENDPOINT)
    SigV4Auth(session.get_credentials(), "aidevops", REGION).add_auth(request)
    req = urllib.request.Request(
        ENDPOINT, method="GET", headers=dict(request.headers)
    )
    with urllib.request.urlopen(req, timeout=10) as response:
        return json.loads(response.read())

def lambda_handler(event, context):
    response = get_account_usage()
    usage = response["monthlyAccountInvestigationHours"]["usage"]
    limit = response["monthlyAccountInvestigationHours"]["limit"]

    cloudwatch.put_metric_data(
        Namespace=NAMESPACE,
        MetricData=[
            {
                "MetricName": METRIC_NAME,
                "Value": usage,
                "Unit": "Count",
            },
        ],
    )

    return {
        "usage": usage,
        "limit": limit,
    }

本記事では monthlyAccountInvestigationHours(調査時間)のみを発行していますが、APIレスポンスには評価時間・システム学習時間も含まれているので、MetricData を追加するだけで監視対象を増やせます。

3メトリクスをまとめて発行する例
def lambda_handler(event, context):
    response = get_account_usage()
    metric_data = []
    for api_key, metric_name in [
        ("monthlyAccountInvestigationHours", "MonthlyInvestigationHours"),
        ("monthlyAccountEvaluationHours", "MonthlyEvaluationHours"),
        ("monthlyAccountSystemLearningHours", "MonthlySystemLearningHours"),
    ]:
        metric_data.append({
            "MetricName": metric_name,
            "Value": response[api_key]["usage"],
            "Unit": "Count",
        })

    cloudwatch.put_metric_data(Namespace=NAMESPACE, MetricData=metric_data)

    return {key: response[key] for key in [
        "monthlyAccountInvestigationHours",
        "monthlyAccountEvaluationHours",
        "monthlyAccountSystemLearningHours",
    ]}

EventBridge Schedulerの設定

上記の内容で実装したLambda関数をEventBridge Schedulerで定期起動します。

CleanShot_2026-05-06_16-17-00@2x.png

ここでの起動頻度でCloudWatchへのメトリクス送信頻度が変わります。

起動頻度 月間起動回数
5分 8,640回
1時間 720回
6時間 120回
1日 30回

CloudWatchカスタムメトリクス

Lambda実行後、CloudWatchコンソールから「メトリクス」>「すべてのメトリクス」>「Custom/DevOpsAgent」配下に MonthlyInvestigationHours が表示されます。

CleanShot_2026-05-01_00-53-09@2x.png

DevOps Agent側の累計調査時間 03:42(3時間42分 ≒ 3.7時間)と、メトリクス側の累計値 3.7時間が一致しています。

CleanShot_2026-05-01_00-54-11@2x.png

CloudWatchアラームの設定

あとはカスタムメトリクスに対してアラームを設定します。

項目
メトリクス Custom/DevOpsAgent/MonthlyInvestigationHours
統計 Maximum
期間 Lambda起動頻度に合わせる(例 5分起動なら5分)
閾値 任意の時間(例 ここでは1時間設定)
評価期間 1
アクション SNS Topic通知

CleanShot_2026-05-06_16-38-04@2x.png

期間はLambda起動頻度と揃えると、データポイント1点ごとに評価できます。

サンプルCloudFormation

ここまでのLambda・EventBridge Scheduler・CloudWatchアラーム・SNSトピックまでを一括でデプロイするCloudFormationテンプレートはこちらです。

以下のリンクから1クリックでデプロイできます。

Launch Stack

スタック作成画面で以下のパラメータを入力します。

パラメータ 説明 デフォルト
ResourcePrefix 作成するリソースの名前プレフィックス devops-agent-usage
Schedule Lambdaの起動頻度(5min/1hour/6hours/1day 1hour
AlarmThresholdHours アラームの閾値(時間) 160
NotificationEmail アラーム通知先メールアドレス (入力必須)

テンプレートは以下のGitHubリポジトリで公開しています。

https://github.com/nyankotaro/cm-devops-agent-usage-alarm/blob/main/template.yaml

動作確認

スタック作成完了後、CloudFormationのOutputsから LambdaFunctionName を確認してLambdaを手動実行します。

aws lambda invoke \
  --function-name devops-agent-usage-publisher \
  --cli-binary-format raw-in-base64-out \
  --payload '{}' \
  /dev/stdout

レスポンスに usagelimit が含まれていれば成功です。

{"usage": 2.385, "limit": 200}

あとはCloudWatchアラームが発火することでSNSトピックに通知が届きます。

CleanShot_2026-05-06_17-18-16@2x.png
CleanShot_2026-05-06_17-17-33@2x.png

今回は簡易的にSNS通知のみ実装しましたが、運用環境に合わせてSlack通知などの実装も検討してみてください。

最後に

DevOps Agentの月間総稼働時間を get-account-usage API + Lambda + CloudWatchカスタムメトリクスでアラート通知する仕組みを構築しました。

API側で月初リセットされた累計値を取得できるため、Lambdaは値をそのまま発行するだけで済み、実装はシンプルにまとまりました。

ちなみに5/1 UTC 00:00:00 に月初リセットされると以下のようになります。

CleanShot_2026-05-06_17-33-07@2x.png

アカウント上限到達警告や任意の時間予算など、運用に直結する閾値を月間ベースで監視できるようになるので、DevOps Agent運用時の参考になれば幸いです。

以上、たかやま(@nyan_kotaroo)でした。

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事