CloudWatch アラームは、aws cloudwatch put-metric-alarm の1コマンドで作れます。 通知先の SNS トピックを先に用意し、その ARN を --alarm-actions に渡せば、しきい値を超えたときに通知が届く仕組みが完成します。

この記事では、SNS トピックの作成からカスタムメトリクスの送信、値の確認、アラーム作成、通知テスト、削除までを1本の流れで進めます。各段のコマンドと出力をそのまま載せているので、上から順にコピーすれば同じ結果を確かめられます。後半には put-metric-alarm の主要オプション早見表、エラー文と直し方、boto3 版、複数のアラームを JSON 定義からまとめて作るスクリプトを用意しました。

確認環境:Ubuntu 24.04、AWS CLI 1.46.1、Python 3.11、boto3 1.43.103。AWS の API をローカルで再現するツール(moto 5.2.3)で実行しました。掲載するコマンドは接続先の指定を外し、実際の AWS でそのまま使える形にしています。日時は ISO 8601 で表示する設定(cli_timestamp_format = iso8601)にしており、出力の時刻は日本時間です。

CloudWatch アラーム作成の早見表(手順 → コマンド)

手順 やること コマンド
1 通知先のトピックを作る aws sns create-topic --name ops-alert
2 通知の受け取り先を登録する aws sns subscribe --topic-arn ARN --protocol email --notification-endpoint アドレス
3 カスタムメトリクスを送る aws cloudwatch put-metric-data --namespace MyApp --metric-name QueueDepth --value 48
4 届いた値を確かめる aws cloudwatch get-metric-statistics --namespace MyApp --metric-name QueueDepth --start-time ... --end-time ... --period 300 --statistics Maximum
5 アラームを作る aws cloudwatch put-metric-alarm --alarm-name 名前 --namespace ... --metric-name ... --statistic ... --period ... --evaluation-periods ... --threshold ... --comparison-operator ... --alarm-actions ARN
6 設定を確かめる aws cloudwatch describe-alarms --alarm-names 名前
7 通知をテストする aws cloudwatch set-alarm-state --alarm-name 名前 --state-value ALARM --state-reason "通知テスト"
8 通知を一時的に止める/戻す aws cloudwatch disable-alarm-actions --alarm-names 名前 / enable-alarm-actions
9 アラームを消す aws cloudwatch delete-alarms --alarm-names 名前

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「CloudWatchアラームをAWS CLIで作成|SNS通知・カスタム指標」

全体の流れ

flowchart LR
    A[アプリやバッチ] -->|put-metric-data| B[CloudWatch メトリクス]
    B -->|Period ごとに集計| C[アラーム]
    C -->|状態が変わる| D[SNS トピック]
    D --> E[メール]
    D --> F[SQS キュー]

例として、ワーカーが処理待ちの件数を MyApp 名前空間の QueueDepth というメトリクスで送り、5分ごとの最大値が50件以上になった回数が、直近3回のうち2回あれば通知するアラームを作ります。

手順1:通知先の SNS トピックを作る

$ aws sns create-topic --name ops-alert
{
    "TopicArn": "arn:aws:sns:ap-northeast-1:123456789012:ops-alert"
}

返ってきた ARN を、あとで --alarm-actions に渡します。同じ名前でもう一度実行すると、既存のトピックの ARN がそのまま返るので、変数に入れる書き方が便利です。

$ TOPIC_ARN=$(aws sns create-topic --name ops-alert --query TopicArn --output text)
$ echo $TOPIC_ARN
arn:aws:sns:ap-northeast-1:123456789012:ops-alert

手順2:通知の受け取り先を登録する(subscribe)

メールで受け取る場合は次のコマンドです。

aws sns subscribe \
  --topic-arn "$TOPIC_ARN" \
  --protocol email \
  --notification-endpoint ops@example.com

公式リファレンスによると、メール(email)や HTTP/HTTPS の受け取り先は、届いた確認メッセージで承認するまで有効になりません。承認前の応答は "SubscriptionArn": "pending confirmation" で、確認用のトークンは2日間有効です。アラームを作る前に、確認メールのリンクを開いて承認を済ませておきます。

--protocol 受け取り先(--notification-endpoint) 承認
email メールアドレス 確認メールで承認
email-json メールアドレス(JSON 形式で届く) 確認メールで承認
https / http URL エンドポイント側で承認
sqs キューの ARN 同じアカウントなら不要
lambda 関数の ARN 同じアカウントなら不要
sms 電話番号 ―

メールを使わずに通知の経路を確かめる(SQS で受ける)

手元で通知の中身を見たいときは、SQS キューを受け取り先にすると CLI だけで確認できます。SNS がキューへ書き込めるよう、キューのアクセスポリシーで sqs:SendMessage を許可します(公式ドキュメントに載っているポリシーの形です)。

qpolicy.json:

{
  "Policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"sns.amazonaws.com\"},\"Action\":\"sqs:SendMessage\",\"Resource\":\"arn:aws:sqs:ap-northeast-1:123456789012:alarm-inbox\",\"Condition\":{\"ArnEquals\":{\"aws:SourceArn\":\"arn:aws:sns:ap-northeast-1:123456789012:ops-alert\"}}}]}"
}
$ QUEUE_URL=$(aws sqs create-queue --queue-name alarm-inbox --query QueueUrl --output text)

$ aws sqs get-queue-attributes --queue-url "$QUEUE_URL" --attribute-names QueueArn --query Attributes.QueueArn --output text
arn:aws:sqs:ap-northeast-1:123456789012:alarm-inbox

$ aws sqs set-queue-attributes --queue-url "$QUEUE_URL" --attributes file://qpolicy.json

$ aws sns subscribe --topic-arn "$TOPIC_ARN" --protocol sqs \
    --notification-endpoint arn:aws:sqs:ap-northeast-1:123456789012:alarm-inbox
{
    "SubscriptionArn": "arn:aws:sns:ap-northeast-1:123456789012:ops-alert:1c0639f8-9d1b-49bf-bdd1-8a0ac5f6217a"
}

$ aws sns list-subscriptions-by-topic --topic-arn "$TOPIC_ARN" --query 'Subscriptions[].[Protocol,Endpoint]' --output text
sqs arn:aws:sqs:ap-northeast-1:123456789012:alarm-inbox

トピックに1通送って、キューに届くことを確かめます。

$ aws sns publish --topic-arn "$TOPIC_ARN" --subject "notification route check" --message "hello from ops-alert"
{
    "MessageId": "7a4f646b-d8ea-4028-8261-132447aad7c3"
}

$ aws sqs receive-message --queue-url "$QUEUE_URL" --wait-time-seconds 1 \
    --query 'Messages[0].Body' --output text | jq '{Type, Subject, Message, TopicArn}'
{
  "Type": "Notification",
  "Subject": "notification route check",
  "Message": "hello from ops-alert",
  "TopicArn": "arn:aws:sns:ap-northeast-1:123456789012:ops-alert"
}

先に sns publish で経路を確かめておくと、あとで通知が届かないときに「SNS より後ろ」か「アラーム側」かを切り分けられます。

手順3:カスタムメトリクスを送る(put-metric-data)

EC2 の CPU 使用率などは AWS が自動で記録しますが、アプリ独自の数値は put-metric-data で送ります。

$ aws cloudwatch put-metric-data --namespace MyApp --metric-name QueueDepth \
    --dimensions Service=worker --unit Count --value 12 --timestamp 2026-10-05T05:57:00Z

$ aws cloudwatch put-metric-data --namespace MyApp --metric-name QueueDepth \
    --dimensions Service=worker --unit Count --value 48 --timestamp 2026-10-05T06:02:00Z

$ aws cloudwatch put-metric-data --namespace MyApp --metric-name QueueDepth \
    --dimensions Service=worker --unit Count --value 30 --timestamp 2026-10-05T06:02:00Z

成功すると何も出力されません。--timestamp を省くと、送信した時刻で記録されます。

オプション 意味 例
--namespace メトリクスの入れ物。自分で決める MyApp
--metric-name メトリクスの名前 QueueDepth
--dimensions 系列を分けるラベル。名前=値 で書く Service=worker
--value 値 48
--unit 単位 Count Seconds Percent Bytes など
--timestamp 記録する時刻(省略時は現在) 2026-10-05T06:02:00Z
--metric-data 複数のメトリクスを JSON でまとめて送る file://metrics.json

複数のメトリクスを1回で送るときは、JSON ファイルにまとめます。StatisticValues を使うと、手元で集計済みの値(件数・合計・最小・最大)を1件として送れます。

metrics.json:

[
  {"MetricName": "QueueDepth", "Dimensions": [{"Name": "Service", "Value": "worker"}], "Unit": "Count", "Value": 75},
  {"MetricName": "ErrorCount", "Dimensions": [{"Name": "Service", "Value": "worker"}], "Unit": "Count",
   "StatisticValues": {"SampleCount": 4, "Sum": 6, "Minimum": 0, "Maximum": 3}}
]
$ aws cloudwatch put-metric-data --namespace MyApp --metric-data file://metrics.json

$ aws cloudwatch list-metrics --namespace MyApp
{
    "Metrics": [
        {
            "Namespace": "MyApp",
            "MetricName": "QueueDepth",
            "Dimensions": [
                {
                    "Name": "Service",
                    "Value": "worker"
                }
            ]
        },
        {
            "Namespace": "MyApp",
            "MetricName": "ErrorCount",
            "Dimensions": [
                {
                    "Name": "Service",
                    "Value": "worker"
                }
            ]
        }
    ]
}

--dimensions の書き方は、コマンドによって違います。 put-metric-data では Service=worker、get-metric-statistics と put-metric-alarm では Name=Service,Value=worker です。ここを取り違えると、後述の Parameter validation failed が表示されます。

手順4:届いた値を確かめる(get-metric-statistics)

アラームを作る前に、アラームに指定する予定の名前空間・メトリクス名・ディメンション・統計で値が取れることを確かめます。

$ aws cloudwatch get-metric-statistics --namespace MyApp --metric-name QueueDepth \
    --dimensions Name=Service,Value=worker \
    --start-time 2026-10-05T05:09:00Z --end-time 2026-10-05T06:14:00Z \
    --period 300 --statistics Average Maximum Sum SampleCount
{
    "Label": "QueueDepth",
    "Datapoints": [
        {
            "Timestamp": "2026-10-05T14:57:00+09:00",
            "SampleCount": 1.0,
            "Average": 12.0,
            "Sum": 12.0,
            "Maximum": 12.0,
            "Unit": "Count"
        },
        {
            "Timestamp": "2026-10-05T15:02:00+09:00",
            "SampleCount": 2.0,
            "Average": 39.0,
            "Sum": 78.0,
            "Maximum": 48.0,
            "Unit": "Count"
        },
        {
            "Timestamp": "2026-10-05T15:07:00+09:00",
            "SampleCount": 1.0,
            "Average": 75.0,
            "Sum": 75.0,
            "Maximum": 75.0,
            "Unit": "Count"
        }
    ]
}

15:02 の区間には 48 と 30 の2件を送ったので、SampleCount は 2、Average は 39、Maximum は 48、Sum は 78 になっています。同じ5分間でも、どの統計を選ぶかで値が変わることが分かります。

統計 意味 向いているメトリクスの例
Average 区間内の平均 使用率、応答時間
Maximum / Minimum 区間内の最大・最小 滞留件数、空き容量
Sum 区間内の合計 エラー件数、リクエスト数
SampleCount 区間内に届いたデータの件数 死活確認(届いているかどうか)

時刻順の一覧にするなら --query で並べ替えます。

$ aws cloudwatch get-metric-statistics --namespace MyApp --metric-name QueueDepth \
    --dimensions Name=Service,Value=worker \
    --start-time 2026-10-05T05:09:00Z --end-time 2026-10-05T06:14:00Z \
    --period 300 --statistics Maximum \
    --query 'sort_by(Datapoints,&Timestamp)[].[Timestamp,Maximum]' --output text
2026-10-05T14:57:00+09:00   12.0
2026-10-05T15:02:00+09:00   48.0
2026-10-05T15:07:00+09:00   75.0

ディメンションの値が1文字でも違うと、別の系列として扱われ、結果は空になります。

$ aws cloudwatch get-metric-statistics --namespace MyApp --metric-name QueueDepth \
    --dimensions Name=Service,Value=api \
    --start-time 2026-10-05T05:09:00Z --end-time 2026-10-05T06:14:00Z \
    --period 300 --statistics Maximum
{
    "Label": "QueueDepth",
    "Datapoints": []
}

Datapoints が空のままアラームを作ると、アラームは評価するデータを得られません。 値が取れることを確かめてから次へ進みます。

手順5:アラームを作る(put-metric-alarm)

aws cloudwatch put-metric-alarm \
  --alarm-name worker-queue-depth-high \
  --alarm-description "キューの滞留が50件以上" \
  --namespace MyApp \
  --metric-name QueueDepth \
  --dimensions Name=Service,Value=worker \
  --statistic Maximum \
  --period 300 \
  --evaluation-periods 3 \
  --datapoints-to-alarm 2 \
  --threshold 50 \
  --comparison-operator GreaterThanOrEqualToThreshold \
  --treat-missing-data notBreaching \
  --alarm-actions "$TOPIC_ARN" \
  --ok-actions "$TOPIC_ARN"

成功すると何も出力されません。このコマンドの意味を1行ずつ読むと次のとおりです。

指定 意味
--statistic Maximum --period 300 5分ごとの最大値を1つのデータポイントにする
--threshold 50 --comparison-operator GreaterThanOrEqualToThreshold 50以上を「しきい値超え」とみなす
--evaluation-periods 3 --datapoints-to-alarm 2 直近3つのデータポイントのうち2つが超えていたら ALARM にする
--treat-missing-data notBreaching データが無い区間は「超えていない」とみなす
--alarm-actions / --ok-actions ALARM になったとき、OK に戻ったときにトピックへ通知する

put-metric-alarm の主要オプション早見表

取りうる値と制約は、公式の API リファレンス(PutMetricAlarm)で確認した内容です。

オプション 取りうる値 補足
--alarm-name 1〜255文字 必須。リージョン内で一意。同じ名前で実行すると上書き
--alarm-description 0〜1024文字 通知にも載るので、何が起きたかを書く
--namespace / --metric-name 各1〜255文字 get-metric-statistics で確かめたものと同じにする
--dimensions Name=...,Value=... を最大30個 メトリクスを送ったときと同じ組み合わせにする
--statistic SampleCount Average Sum Minimum Maximum --extended-statistic とどちらか一方
--extended-statistic p90 p99 などのパーセンタイル、tm90、IQM など 応答時間の上位何%を見たいとき
--period 10、20、30、または60の倍数(秒) 1つのデータポイントを作る集計の長さ
--evaluation-periods 1以上の整数 直近いくつのデータポイントを見るか(N)
--datapoints-to-alarm 1以上の整数 そのうちいくつ超えたら ALARM か(M)
--threshold 数値(小数可) 比べる値
--comparison-operator GreaterThanOrEqualToThreshold GreaterThanThreshold LessThanThreshold LessThanOrEqualToThreshold 異常検出のバンドと比べる LessThanLowerOrGreaterThanUpperThreshold LessThanLowerThreshold GreaterThanUpperThreshold もある
--treat-missing-data missing(既定) notBreaching breaching ignore データが無い区間の扱い
--alarm-actions ARN を最大5個 ALARM になったときの動作(SNS トピックなど)
--ok-actions ARN を最大5個 OK に戻ったときの動作
--insufficient-data-actions ARN を最大5個 INSUFFICIENT_DATA になったときの動作
--actions-enabled / --no-actions-enabled 既定は有効 作成時から通知を止めておくなら --no-actions-enabled
--unit Count Seconds Percent Bytes など メトリクスの単位
--tags Key=...,Value=... アラームにタグを付ける

Period と EvaluationPeriods には掛け算の上限があります。 公式リファレンスによると、Period × EvaluationPeriods は7日(604,800秒)以内、Period が1時間(3,600秒)未満のアラームでは1日(86,400秒)以内です。たとえば Period 300 なら EvaluationPeriods は 288 までです。

M out of N の考え方

--evaluation-periods(N)と --datapoints-to-alarm(M)を別の値にすると「N個中M個」のアラームになります。超えているデータポイントは連続していなくてもかまいません。

N M 動き 向いている場面
1 1 1回超えたらすぐ ALARM 止まったらすぐ知りたい指標
3 3 3回連続で超えたら ALARM 一時的な山を通知から外したい
3 2 直近3回のうち2回で ALARM 断続的に超える状態も拾いたい

--treat-missing-data の選び方

値 データが無い区間の扱い 向いている場面
missing(既定) 判断材料にしない。評価範囲のすべてが欠けると INSUFFICIENT_DATA になる 常にデータが届くメトリクス
notBreaching しきい値内(正常)とみなす エラー件数のように、何も起きないと送られないメトリクス
breaching しきい値超え(異常)とみなす 定期送信の死活確認。届かないこと自体を知りたい
ignore いまの状態を保つ 欠けても状態を動かしたくない

手順6:設定を確かめる(describe-alarms)

$ aws cloudwatch describe-alarms --alarm-names worker-queue-depth-high \
    --query 'MetricAlarms[0].{Name:AlarmName,Arn:AlarmArn,Metric:MetricName,Namespace:Namespace,Dimensions:Dimensions,Statistic:Statistic,Period:Period,EvaluationPeriods:EvaluationPeriods,DatapointsToAlarm:DatapointsToAlarm,Threshold:Threshold,Operator:ComparisonOperator,TreatMissingData:TreatMissingData,ActionsEnabled:ActionsEnabled,AlarmActions:AlarmActions,OKActions:OKActions}'
{
    "Name": "worker-queue-depth-high",
    "Arn": "arn:aws:cloudwatch:ap-northeast-1:123456789012:alarm:worker-queue-depth-high",
    "Metric": "QueueDepth",
    "Namespace": "MyApp",
    "Dimensions": [
        {
            "Name": "Service",
            "Value": "worker"
        }
    ],
    "Statistic": "Maximum",
    "Period": 300,
    "EvaluationPeriods": 3,
    "DatapointsToAlarm": 2,
    "Threshold": 50.0,
    "Operator": "GreaterThanOrEqualToThreshold",
    "TreatMissingData": "notBreaching",
    "ActionsEnabled": true,
    "AlarmActions": [
        "arn:aws:sns:ap-northeast-1:123456789012:ops-alert"
    ],
    "OKActions": [
        "arn:aws:sns:ap-northeast-1:123456789012:ops-alert"
    ]
}

一覧で見比べるときは表形式が便利です。

$ aws cloudwatch describe-alarms --alarm-name-prefix worker- \
    --query 'MetricAlarms[].[AlarmName,MetricName,Statistic,Period,Threshold]' --output table
---------------------------------------------------------------------
|                          DescribeAlarms                           |
+--------------------------+-------------+----------+------+--------+
|  worker-queue-depth-high |  QueueDepth |  Maximum |  300 |  50.0  |
+--------------------------+-------------+----------+------+--------+
絞り込み方 オプション
名前を指定 --alarm-names 名前1 名前2
名前の先頭で絞る --alarm-name-prefix worker-
状態で絞る --state-value ALARM(OK INSUFFICIENT_DATA も指定可)
あるメトリクスに付いたアラームを探す aws cloudwatch describe-alarms-for-metric --namespace MyApp --metric-name QueueDepth --dimensions Name=Service,Value=worker

アラームの状態は3つあります。

状態 意味
OK メトリクスがしきい値の内側にある
ALARM メトリクスがしきい値の外側にある
INSUFFICIENT_DATA 作成直後、またはデータが足りず判断できない

公式ドキュメントによると、作成直後のアラームは INSUFFICIENT_DATA から始まり、評価できるデータがそろうと OK か ALARM に移ります。

同じ名前で実行すると設定がまるごと置き換わる

put-metric-alarm に「一部だけ更新する」動きはありません。しきい値だけ変えるつもりで他のオプションを省くと、省いた項目は消えます。

$ aws cloudwatch put-metric-alarm --alarm-name worker-queue-depth-high \
    --namespace MyApp --metric-name QueueDepth --dimensions Name=Service,Value=worker \
    --statistic Maximum --period 300 --evaluation-periods 3 --datapoints-to-alarm 2 \
    --threshold 80 --comparison-operator GreaterThanOrEqualToThreshold

$ aws cloudwatch describe-alarms --alarm-names worker-queue-depth-high \
    --query 'MetricAlarms[0].[Threshold,AlarmDescription,TreatMissingData,AlarmActions]'
[
    80.0,
    null,
    null,
    []
]

しきい値は 80 になりましたが、説明・欠損データの扱い・通知先が空になりました。 変更するときは、作成時のコマンド全体をスクリプトやファイルに残しておき、値を書き換えて全体を実行し直します。

手順7:通知をテストする(set-alarm-state)

メトリクスが実際にしきい値を超えるのを待たなくても、set-alarm-state でアラームの状態を一時的に変えられます。

$ aws cloudwatch set-alarm-state --alarm-name worker-queue-depth-high \
    --state-value ALARM --state-reason "通知テスト"

$ aws cloudwatch describe-alarms --alarm-names worker-queue-depth-high \
    --query 'MetricAlarms[0].[StateValue,StateReason,StateUpdatedTimestamp]'
[
    "ALARM",
    "通知テスト",
    "2026-10-05T15:09:33.890000+09:00"
]

$ aws cloudwatch describe-alarms --state-value ALARM --query 'MetricAlarms[].AlarmName' --output text
worker-queue-depth-high

公式の API リファレンス(SetAlarmState)には、次のように書かれています。

  • テスト用に状態を一時的に設定する操作で、変更後の状態が前と違うとき、その状態に設定したアクションが実行される(ALARM に変えれば --alarm-actions の SNS トピックへ通知が送られる)。
  • メトリクスアラームはすぐに(多くは数秒で)本来の状態に戻る。戻りが速いので、変化はアラームの履歴(describe-alarm-history)で確かめる。

今回のローカル環境ではメトリクスによる自動の再評価が動かないため、状態は指定した値のまま残りました。テストを終えるときは OK に戻しておくと、--ok-actions の通知も合わせて確かめられます。

$ aws cloudwatch set-alarm-state --alarm-name worker-queue-depth-high \
    --state-value OK --state-reason "テスト終了"

$ aws cloudwatch describe-alarms --state-value ALARM --query 'length(MetricAlarms)'
0
オプション 取りうる値
--state-value OK ALARM INSUFFICIENT_DATA
--state-reason 必須。0〜1023文字。履歴に残る説明
--state-reason-data 任意。JSON 形式の補足(4000文字まで)

手順8:通知を止める・アラームを消す

作業中だけ通知を止めたいときは、アラームを消さずにアクションを無効にします。

$ aws cloudwatch disable-alarm-actions --alarm-names worker-queue-depth-high

$ aws cloudwatch describe-alarms --alarm-names worker-queue-depth-high --query 'MetricAlarms[0].ActionsEnabled'
false

$ aws cloudwatch enable-alarm-actions --alarm-names worker-queue-depth-high

不要になったら削除します。名前は複数並べられます。

$ aws cloudwatch delete-alarms --alarm-names worker-queue-depth-high

$ aws cloudwatch describe-alarms --alarm-names worker-queue-depth-high
{
    "MetricAlarms": [],
    "CompositeAlarms": []
}

通知先も片付けるなら、購読の解除とトピックの削除を行います。

aws sns unsubscribe --subscription-arn "サブスクリプションのARN"
aws sns delete-topic --topic-arn "$TOPIC_ARN"

エラー文と直し方(実際の出力)

指定を誤ったときに表示されたメッセージです。エラーになったコマンドではアラームは作られません。

Dimensions の書き方が違う

$ aws cloudwatch put-metric-alarm --alarm-name x --namespace MyApp --metric-name QueueDepth \
    --threshold 50 --comparison-operator GreaterThanOrEqualToThreshold \
    --evaluation-periods 1 --period 60 --statistic Maximum --dimensions Service=worker
Parameter validation failed:
Missing required parameter in Dimensions[0]: "Name"
Missing required parameter in Dimensions[0]: "Value"
Unknown parameter in Dimensions[0]: "Service", must be one of: Name, Value

put-metric-data と同じ Service=worker で書くと表示されます。アラームでは --dimensions Name=Service,Value=worker と書きます。

Period や EvaluationPeriods の値が範囲外・数値でない

$ aws cloudwatch put-metric-alarm ... --evaluation-periods 1 --period 0 --statistic Maximum
Parameter validation failed:
Invalid value for parameter Period, value: 0, valid min value: 1

$ aws cloudwatch put-metric-alarm ... --evaluation-periods 0 --period 60 --statistic Maximum
Parameter validation failed:
Invalid value for parameter EvaluationPeriods, value: 0, valid min value: 1

$ aws cloudwatch put-metric-alarm ... --evaluation-periods 1 --period 5m --statistic Maximum
invalid literal for int() with base 10: '5m'

$ aws cloudwatch put-metric-alarm ... --threshold high ...
aws: error: argument --threshold: invalid float value: 'high'

--period は秒の整数で書きます。5分なら 300 です。Parameter validation failed は、リクエストを送る前に CLI が検査して止めたことを表します。

統計の指定が合っていない

$ aws cloudwatch put-metric-alarm ... --period 60 --extended-statistic median

An error occurred (InvalidParameterValue) when calling the PutMetricAlarm operation: The value median for parameter ExtendedStatistic is not supported.

$ aws cloudwatch put-metric-alarm ... --period 60 --extended-statistic p90 --evaluate-low-sample-count-percentile skip

An error occurred (ValidationError) when calling the PutMetricAlarm operation: Option skip is not supported. Supported options for parameter EvaluateLowSampleCountPercentile are evaluate and ignore.

中央値を見たいときは --extended-statistic p50 のようにパーセンタイルで指定します。--statistic に書けるのは SampleCount Average Sum Minimum Maximum の5つで、--statistic と --extended-statistic はどちらか一方を選びます。

メトリクス取得・送信側のエラー

$ aws cloudwatch get-metric-statistics --namespace MyApp --metric-name QueueDepth \
    --start-time 2026-10-05T05:09:00Z --end-time 2026-10-05T06:14:00Z --period 300

An error occurred (InvalidParameterCombination) when calling the GetMetricStatistics operation: Must specify either Statistics or ExtendedStatistics

$ aws cloudwatch get-metric-statistics --namespace MyApp --metric-name QueueDepth \
    --start-time 2026-10-05T06:14:00Z --end-time 2026-10-05T05:09:00Z --period 300 --statistics Maximum

An error occurred (InvalidParameterValue) when calling the GetMetricStatistics operation: The parameter StartTime must be less than the parameter EndTime.

$ aws cloudwatch put-metric-data --namespace MyApp \
    --metric-data '[{"MetricName":"ErrorCount","Value":1,"StatisticValues":{"SampleCount":1,"Sum":1,"Minimum":1,"Maximum":1}}]'

An error occurred (InvalidParameterCombination) when calling the PutMetricData operation: The parameters MetricData.member.1.Value and MetricData.member.1.StatisticValues are mutually exclusive and you have specified both.

$ aws cloudwatch put-metric-data --namespace MyApp \
    --metric-data '[{"MetricName":"ErrorCount","StatisticValues":{"SampleCount":1,"Sum":1}}]'
Parameter validation failed:
Missing required parameter in MetricData[0].StatisticValues: "Minimum"
Missing required parameter in MetricData[0].StatisticValues: "Maximum"

set-alarm-state の状態名が違う

$ aws cloudwatch set-alarm-state --alarm-name worker-queue-depth-high --state-value NG --state-reason x

An error occurred (ValidationError) when calling the SetAlarmState operation: 1 validation error detected: Value 'NG' at 'stateValue' failed to satisfy constraint: Member must satisfy enum value set: [INSUFFICIENT_DATA, ALARM, OK]

エラーの早見表

メッセージの先頭 原因 直し方
the following arguments are required: --alarm-name 必須オプションの不足 表示されたオプションを足す
Parameter validation failed: ... Dimensions[0] ディメンションの書式違い Name=...,Value=... で書く
Invalid value for parameter Period Period が範囲外 10、20、30、または60の倍数にする
invalid literal for int() 整数のオプションに文字が混ざっている 秒の整数で書く
InvalidParameterValue ... ExtendedStatistic is not supported 拡張統計の書式違い p90 のように書く
InvalidParameterCombination ... Must specify either Statistics or ExtendedStatistics 統計の指定がない --statistics Maximum などを足す
StartTime must be less than the parameter EndTime 開始と終了が逆 時刻を入れ替える
ValidationError ... stateValue 状態名の誤り OK ALARM INSUFFICIENT_DATA から選ぶ

boto3 で同じ流れを書く

CLI と同じ内容を Python(boto3)で書いた完成形です。オプション名がキャメルケースの引数になる点以外は、CLI と1対1で対応します。

alarm_boto3.py:

import boto3

REGION = "ap-northeast-1"
sns = boto3.client("sns", region_name=REGION)
cw = boto3.client("cloudwatch", region_name=REGION)

# 1. 通知先のトピック(同じ名前なら既存の ARN が返る)
topic_arn = sns.create_topic(Name="ops-alert")["TopicArn"]

# 2. カスタムメトリクスを送る
cw.put_metric_data(
    Namespace="MyApp",
    MetricData=[{
        "MetricName": "QueueDepth",
        "Dimensions": [{"Name": "Service", "Value": "worker"}],
        "Unit": "Count",
        "Value": 64,
    }],
)

# 3. アラームを作る(同じ名前で呼ぶと設定が上書きされる)
cw.put_metric_alarm(
    AlarmName="worker-queue-depth-high",
    AlarmDescription="キューの滞留が50件以上",
    Namespace="MyApp",
    MetricName="QueueDepth",
    Dimensions=[{"Name": "Service", "Value": "worker"}],
    Statistic="Maximum",
    Period=300,
    EvaluationPeriods=3,
    DatapointsToAlarm=2,
    Threshold=50,
    ComparisonOperator="GreaterThanOrEqualToThreshold",
    TreatMissingData="notBreaching",
    AlarmActions=[topic_arn],
    OKActions=[topic_arn],
)

# 4. 設定を確認する
alarm = cw.describe_alarms(AlarmNames=["worker-queue-depth-high"])["MetricAlarms"][0]
for key in ("AlarmName", "Statistic", "Period", "EvaluationPeriods",
            "DatapointsToAlarm", "Threshold", "ComparisonOperator",
            "TreatMissingData", "AlarmActions"):
    print(f"{key:20} {alarm[key]}")

# 5. 通知テスト:状態を一時的に ALARM にする
cw.set_alarm_state(
    AlarmName="worker-queue-depth-high",
    StateValue="ALARM",
    StateReason="通知テスト(boto3)",
)
alarm = cw.describe_alarms(AlarmNames=["worker-queue-depth-high"])["MetricAlarms"][0]
print("state:", alarm["StateValue"], "/", alarm["StateReason"])
$ python3 alarm_boto3.py
AlarmName            worker-queue-depth-high
Statistic            Maximum
Period               300
EvaluationPeriods    3
DatapointsToAlarm    2
Threshold            50.0
ComparisonOperator   GreaterThanOrEqualToThreshold
TreatMissingData     notBreaching
AlarmActions         ['arn:aws:sns:ap-northeast-1:123456789012:ops-alert']
state: ALARM / 通知テスト(boto3)

複数のアラームを JSON 定義からまとめて作る

アラームが増えてきたら、定義を JSON にまとめてスクリプトで流し込むと、設定の見直しや別環境への展開がしやすくなります。共通の値は defaults に書き、アラームごとに違う値だけを alarms に書きます。

alarms.json:

{
  "defaults": {
    "Namespace": "MyApp",
    "Dimensions": [{"Name": "Service", "Value": "worker"}],
    "Period": 300,
    "EvaluationPeriods": 3,
    "DatapointsToAlarm": 2,
    "TreatMissingData": "notBreaching"
  },
  "alarms": [
    {"AlarmName": "worker-queue-depth-high", "MetricName": "QueueDepth", "Statistic": "Maximum",
     "Threshold": 50, "ComparisonOperator": "GreaterThanOrEqualToThreshold"},
    {"AlarmName": "worker-error-count-high", "MetricName": "ErrorCount", "Statistic": "Sum",
     "Threshold": 5, "ComparisonOperator": "GreaterThanThreshold"},
    {"AlarmName": "worker-heartbeat-missing", "MetricName": "Heartbeat", "Statistic": "SampleCount",
     "Threshold": 1, "ComparisonOperator": "LessThanThreshold",
     "Period": 60, "EvaluationPeriods": 5, "DatapointsToAlarm": 5, "TreatMissingData": "breaching"}
  ]
}

3つ目の worker-heartbeat-missing は、1分ごとに届くはずのデータが5分続けて届かないと ALARM になる死活確認の例です。届かない区間を異常とみなすため、TreatMissingData を breaching にしています。

create_alarms.py:

"""alarms.json の定義からアラームをまとめて作る。
使い方: python3 create_alarms.py alarms.json arn:aws:sns:ap-northeast-1:123456789012:ops-alert
"""
import json
import sys

import boto3
from botocore.exceptions import ClientError, ParamValidationError

path, topic_arn = sys.argv[1], sys.argv[2]
with open(path, encoding="utf-8") as f:
    conf = json.load(f)

cw = boto3.client("cloudwatch", region_name="ap-northeast-1")
created, skipped = 0, 0
for item in conf["alarms"]:
    params = {**conf["defaults"], **item}          # 個別の値が共通の値を上書きする
    params.setdefault("AlarmActions", [topic_arn])
    params.setdefault("OKActions", [topic_arn])
    try:
        cw.put_metric_alarm(**params)
        created += 1
        print(f"created  {params['AlarmName']}")
    except (ClientError, ParamValidationError) as e:
        skipped += 1
        print(f"skipped  {item.get('AlarmName')}: {e}")
print(f"created={created} skipped={skipped}")

names = [a["AlarmName"] for a in conf["alarms"]]
for a in cw.describe_alarms(AlarmNames=names)["MetricAlarms"]:
    print(f"{a['AlarmName']:26} {a['MetricName']:11} {a['Statistic']:11} "
          f"{a['ComparisonOperator']:30} {a['Threshold']:>5} "
          f"{a['DatapointsToAlarm']}/{a['EvaluationPeriods']} x {a['Period']}s {a['TreatMissingData']}")
$ python3 create_alarms.py alarms.json arn:aws:sns:ap-northeast-1:123456789012:ops-alert
created  worker-queue-depth-high
created  worker-error-count-high
created  worker-heartbeat-missing
created=3 skipped=0
worker-queue-depth-high    QueueDepth  Maximum     GreaterThanOrEqualToThreshold   50.0 2/3 x 300s notBreaching
worker-error-count-high    ErrorCount  Sum         GreaterThanThreshold             5.0 2/3 x 300s notBreaching
worker-heartbeat-missing   Heartbeat   SampleCount LessThanThreshold                1.0 5/5 x 60s breaching

put_metric_alarm は同じ名前なら上書きなので、このスクリプトは何度実行しても同じ状態になります。定義ファイルを Git で管理すれば、しきい値を変えた履歴も残せます。

CLI だけで済ませたい場合は、aws cloudwatch put-metric-alarm --generate-cli-skeleton でひな形を出し、アラームごとの JSON を --cli-input-json file://名前.json で渡す方法もあります。

作成前のチェックリスト

確認すること 確かめ方
メトリクスに値が届いている get-metric-statistics の Datapoints が空でない
名前空間・メトリクス名・ディメンションがアラームと一致している 手順4のコマンドと put-metric-alarm の指定を見比べる
統計がメトリクスの性質に合っている 件数は Sum、滞留は Maximum、使用率は Average
通知先の承認が済んでいる 確認メールのリンクを開いて承認した
通知の経路が通っている sns publish で1通送って届く
欠損データの扱いを決めた 何も起きないと送られないメトリクスは notBreaching
作成コマンドを残してある 変更時は全体を実行し直すため

よくある質問

Q. アラームを作ったのに通知が届きません。どこから確かめればよいですか? A. 後ろから順に確かめます。まず aws sns publish でトピックに直接1通送り、届けば SNS より後ろは通っています。次に set-alarm-state で ALARM にして届くかを見ます。届かなければ describe-alarms で AlarmActions に ARN が入っているか、ActionsEnabled が true かを確かめます。

Q. アラームの状態が INSUFFICIENT_DATA のままです。 A. アラームが見ているメトリクスにデータが届いていない状態です。get-metric-statistics を、アラームと同じ名前空間・メトリクス名・ディメンション・統計で実行し、Datapoints が返るかを確かめます。空なら、ディメンションの組み合わせがメトリクスの送信時と同じかを見直します。

Q. しきい値だけ変更したいときは? A. put-metric-alarm は設定をまるごと置き換えるので、作成時と同じオプションをすべて付けたうえで --threshold だけ書き換えて実行します。省いたオプションは空になるため、コマンドを残しておくか、JSON 定義から作り直す形にしておくと安心です。

Q. set-alarm-state でテストしたあと、元に戻す操作は必要ですか? A. 公式リファレンスでは、メトリクスアラームは本来の状態にすぐ戻ると説明されています。OK に戻ったときの通知も確かめたい場合は、--state-value OK をもう一度実行します。

まとめ

  • アラーム作成は put-metric-alarm の1コマンド。通知先の SNS トピックを先に作り、ARN を --alarm-actions に渡す。
  • 作る前に get-metric-statistics で値を確かめる。名前空間・メトリクス名・ディメンション・統計をアラームと同じにする。
  • --dimensions の書式はコマンドで違う。送信は Service=worker、取得とアラームは Name=Service,Value=worker。
  • --evaluation-periods(N)と --datapoints-to-alarm(M)で「N個中M個」。一時的な山を通知から外せる。
  • --treat-missing-data はメトリクスの性質で選ぶ。何も起きないと送られないなら notBreaching、死活確認なら breaching。
  • 同じ名前で実行すると設定がまるごと置き換わる。変更時は全オプションを付けて実行する。
  • 通知テストは set-alarm-state。先に sns publish で経路を確かめると切り分けやすい。

参考・出典

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「CloudWatchアラームをAWS CLIで作成|SNS通知・カスタム指標」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?