富士通 Japan 株式会社 Public & Education 事業本部
クラウドサービス事業部の吉村 康良です。
令和3年度のガバメントクラウド先行事業から、ガバメントクラウドを利用したインフラストラクチャの設計に従事し、現在は主にガバメントクラウド上のインフラ運用保守を担当しています。
監視サービスは随時アップデートされており、適宜監視設計を見直すことで、より運用改善につながると考えています。そのポイントを解説します。
はじめに
本記事の対象読者
ガバメントクラウド(デジタル庁の政府共通クラウド基盤)上で AWS を使っている地方公共団体や運用管理補助者の方を主な対象としています。
「Organizations の管理権限がない」「完全閉域ネットワーク」という 2 つの制約の下で、大量アカウント環境における統合監視をどのように実現するか、検討した内容を解説します。
本記事の前提(IaC 方針)
デジタル庁 GCAS ガイドに記載の「インフラ管理を IaC(Infrastructure as Code)化する」という、ガバメントクラウドにおけるモダン化の定義を前提に、構築手順は可能な限り CloudFormation テンプレートで記載しています。CloudFormation で未対応の操作については、AWS CLI や AWS マネジメントコンソールを利用した手順とします。
本記事でわかること:
- CloudWatch OAM で Organizations なしに複数アカウントの監視を集約する方法
- VPC Interface Endpoint(PrivateLink) を使った完全閉域構成
- Network Synthetic Monitor / Syslog Ingestion(2026年6月新機能)によるネットワーク機器監視
- Alarm Mute Rules(2026年1月新機能)によるメンテナンス通知抑止
- AWS DevOps Agent による AI 駆動の効率的な障害調査
ガバメントクラウドの制約
ガバメントクラウド(デジタル庁が主導して整備・運用する政府共通のクラウド基盤)の AWS 環境は、地方公共団体の情報システム標準化のために整備された環境です。各自治体は、デジタル庁が管理する AWS Organizations 配下のアカウントを利用します。
通常の自己管理 AWS 環境 であれば、AWS Organizations を活用して Amazon CloudWatch オブザーバビリティアクセスマネージャー(OAM)のシンクポリシーを組織全体に一括適用できます。
OU にアカウントを追加するだけで監視対象が自動でオンボードされ、大量アカウント環境でもほぼ自動化が実現できます。
# Example sink policy in a standard environment (with Organizations)
Condition:
StringEquals:
aws:PrincipalOrgID: "o-xxxxxxxxxxxx" # All accounts are covered by specifying the Organizations ID
後述の monitoring-account-sink.yaml に記載の Condition 句を、上記の値とします。
しかし、ガバメントクラウド環境には以下の制約があります。
-
AWS Organizations の管理権限が利用できない
自治体はデジタル庁が管理する Organizations に所属するため、OU 操作・SCP・CloudFormation StackSets 等の組織管理機能を自由に使えません。
OAM の Organizations 一括設定も同様に利用できません。 -
閉域ネットワーク(運用管理アカウントを通じたパッチ適用、ウイルス対策ソフトのパターンファイル更新の用途を除きインターネット経由の接続が禁止)
個人番号(マイナンバー)等を扱うシステムの性質上、AWS サービスへの通信も VPC Endpoint 経由に限定されます。
この 2 つの制約を踏まえ、本記事では OAM の個別アカウントリンクと VPC Endpoint による完全閉域構成を用いて、多数の AWS アカウントと、オンプレミスに設置するクラウドと庁舎を接続するために必須のネットワーク機器やオンプレミスサーバを、1 つの「集約アカウント」から統合監視する構成を解説します。
監視対象
| 場所 | リソース |
|---|---|
| AWS(各アカウント) | ALB、NLB、EC2 |
| オンプレミス | ネットワーク機器、オンプレミスサーバ |
監視項目
サーバ監視
| # | 監視項目 |
|---|---|
| 1 | 死活監視 |
| 2 | CPU 使用率 |
| 3 | メモリ使用率 |
| 4 | ディスク使用率 |
| 5 | ログ(Windows イベントログ、テキストログ) |
| 6 | サービス/プロセス監視 |
ネットワーク監視
| # | 監視項目 |
|---|---|
| 1 | 死活監視 |
| 2 | SNMP(性能・状態) |
| 3 | SNMPTrap(障害通知) |
| 4 | Syslog |
目次
- 設計方針
- 全体構成図
- クロスアカウント観測の設定(OAM)
- 完全閉域ネットワークの設定
- サーバ監視の実装
- ネットワーク機器監視の実装
- メンテナンス通知の管理(Alarm Mute Rules)
- AI 駆動の運用効率化(AWS DevOps Agent)
- コストとクォータの管理
- まとめ
1. 設計方針
ガバメントクラウドAWS環境における統合監視実現のポイント
Amazon CloudWatch Observability Access Manager(OAM) は、AWS Organizations を使用しなくても個別アカウントを 1 つずつ監視アカウントにリンクできる仕組みを提供しています。
ガバメントクラウドでは Organizations 管理権限が利用できないため、各ソースアカウントで個別にリンクを作成するアプローチを取ります。
OAM で共有できる観測データの種類は以下のとおりです。
| 共有データの種類 | 内容 |
|---|---|
| CloudWatch メトリクス | 全ネームスペースまたはフィルタ指定 |
| CloudWatch Logs | 全ロググループまたはフィルタ指定 |
| AWS X-Ray Traces | 分散トレーシング |
| Application Insights | アプリケーション監視 |
| CloudWatch Internet Monitor | インターネット経由の可用性監視 |
| 比較項目 | Organizations あり | Organizations なし(OAM 個別リンク) |
|---|---|---|
| アカウント追加方法 | OU 追加で自動オンボード | 各アカウントで手動リンク作成 |
| 最大ソースアカウント数 | 100,000 | 100,000(同じ上限) |
| 共有データ | メトリクス、ログ、X-Ray トレース、Application Insights、Internet Monitor | 同左 |
| 追加コスト | なし | なし |
Organizations がなくても、機能・上限・コストは同等です。
構成のポイント
構成のポイントは、コスト・ネットワーク・運用性の 3 つの観点とします。
特に運用性について、システムの運用保守として発生するメンテナンス作業による計画作業であるのにアラーム通知されるなどで重要なアラートが埋もれてしまうケースが発生するため、抑止機能(ミュートルール)を使うことで重要なアラームのみに絞る対策が必要となります。
| 観点 | 原則 | 実現手段 |
|---|---|---|
| コスト | 重複コストは発生させない | OAM によりソースアカウントのデータを参照 |
| ネットワーク | 完全閉域ネットワーク | VPC Interface Endpoint(PrivateLink)経由のみ |
| 運用性 | アラーム通知の最適化 | Alarm Mute Rules(2026年1月リリース)でメンテナンス時の不要通知を抑止 |
2. 全体構成図
以降に記載の CloudFormation テンプレートや AWS CLI コマンド、AWS マネジメントコンソール の手順はサンプルとなります。
実際の環境に合わせて適宜修正いただく必要があります。
3. クロスアカウント観測の設定(OAM)
Step 1: 集約アカウントでシンクを作成
集約アカウントに CloudFormation テンプレートを展開し、「シンク(Sink)」を作成します。
パラメータ AllowedSourceAccountIds に集約する対象の AWS アカウントID をカンマ区切りで入力します。
# monitoring-account-sink.yaml (deploy in monitoring account)
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudWatch Cross-Account Observability - Monitoring Account Sink
Parameters:
AllowedSourceAccountIds:
Type: CommaDelimitedList
Description: Comma-separated list of source account IDs to allow
# Example: "111111111111,222222222222,333333333333"
Resources:
MonitoringSink:
Type: AWS::Oam::Sink
Properties:
Name: central-monitoring-sink
Policy:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
AWS: "*"
Action:
- oam:CreateLink
- oam:UpdateLink
Resource: "*"
Condition:
StringEquals:
aws:PrincipalAccount: !Ref AllowedSourceAccountIds
Outputs:
SinkArn:
Value: !GetAtt MonitoringSink.Arn
Export:
Name: MonitoringAccountSinkArn
Description: Sink ARN referenced by source-account CloudFormation templates
Step 2: 各ソースアカウントでリンクを作成
各ソースアカウントに CloudFormation テンプレートを展開します。
Step 1 で作成された MonitoringAccountSinkArn をパラメータへ入力します。
# cloudwatch-oam-link.yaml (deploy in each source account)
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudWatch Cross-Account Observability Link
Parameters:
MonitoringAccountSinkArn:
Type: String
Description: ARN of the monitoring account sink
Resources:
ObservabilityLink:
Type: AWS::Oam::Link
Properties:
LabelTemplate: "$AccountName"
ResourceTypes:
- AWS::CloudWatch::Metric
- AWS::Logs::LogGroup
- AWS::XRay::Trace
- AWS::ApplicationInsights::Application
- AWS::InternetMonitor::Monitor
SinkIdentifier: !Ref MonitoringAccountSinkArn
Outputs:
LinkArn:
Value: !GetAtt ObservabilityLink.Arn
Step 3: 集約アカウントでクロスアカウントアラームを作成
OAM のリンクが設定されると、集約アカウントの CloudWatch コンソールから各ソースアカウントのメトリクスをそのまま参照できるようになります。CloudFormation のアラーム定義では Metrics プロパティに AccountId を指定することでクロスアカウント参照が有効になります。
集約アカウントに CloudFormation テンプレートを展開し、アラームを作成します。
テンプレートは最小構成として、EC2のCPU使用率のクロスアカウントアラームのみ作成するサンプルとなります。
# monitoring-account-alarms.yaml (deploy in monitoring account)
AWSTemplateFormatVersion: '2010-09-09'
Description: Cross-Account CloudWatch Alarms - Monitoring Account
Parameters:
SourceAccountId:
Type: String
Description: Source account ID to monitor
TargetInstanceId:
Type: String
Description: EC2 instance ID to monitor
AlertTopicArn:
Type: String
Description: SNS topic ARN for notifications
Resources:
# Cross-account alarm for EC2 high CPU usage
CrossAcctEC2HighCPUAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: !Sub "${SourceAccountId}-EC2-HighCPU-${TargetInstanceId}"
AlarmDescription: !Sub "High CPU alarm for EC2 in source account ${SourceAccountId}"
Metrics:
- Id: m1
AccountId: !Ref SourceAccountId
MetricStat:
Metric:
Namespace: AWS/EC2
MetricName: CPUUtilization
Dimensions:
- Name: InstanceId
Value: !Ref TargetInstanceId
Period: 300
Stat: Average
ReturnData: true
ComparisonOperator: GreaterThanOrEqualToThreshold
Threshold: 80
EvaluationPeriods: 3
AlarmActions:
- !Ref AlertTopicArn
TreatMissingData: notBreaching
4. 完全閉域ネットワークの設定
ガバメントクラウドの閉域ネットワーク要件を満たすため、AWS サービスとの通信に VPC Interface Endpoint(PrivateLink)を使用します。インターネットゲートウェイまたはNATゲートウェイは不要で、通信はすべて AWS の内部ネットワーク上に閉じます。
❌ ガバメントクラウドでは禁止
[EC2/オンプレミスサーバ]
↓
[インターネット]
↓
[AWS サービスエンドポイント]
✅ ガバメントクラウド対応
[EC2/オンプレミスサーバ]
↓
[VPC Interface Endpoint (PrivateLink)]
↓(AWS 内部ネットワーク)
[AWS サービスエンドポイント]
必要な VPC エンドポイント一覧
本構成で必要な VPC Interface Endpoint は以下のとおりです。
| エンドポイントサービス名 | 用途 |
|---|---|
com.amazonaws.{region}.monitoring |
CloudWatch メトリクスの送信 |
com.amazonaws.{region}.logs |
CloudWatch Logs への送信 |
com.amazonaws.{region}.syslog-logs |
Syslog Ingestion(2026年6月新機能) ネットワーク機器からの Syslog 直接受信 |
com.amazonaws.{region}.secretsmanager |
Secrets Manager へのアクセス (Lambda から Webhook シークレット取得) |
com.amazonaws.{region}.event-ai |
AWS DevOps Agent Webhook Events |
PrivateDnsEnabled: true を設定すると、VPC 内のクライアントは monitoring.ap-northeast-1.amazonaws.com などの名前を解決した際に、Endpoint のプライベート IP を自動的に取得できます。
VPC エンドポイントの作成は後述の章で実施します。
オンプレミスからの接続フロー
[オンプレミスサーバ(CloudWatch Agent)]
↓
[AWS Direct Connect]
↓
[VPC Interface Endpoint (PrivateLink)]
↓
[CloudWatch / CloudWatch Logs]
Route 53 Resolver を使って、オンプレミス DNS から VPC Endpoint のプライベート DNS 名へ転送することで、オンプレミスサーバやネットワーク機器でも名前解決できるようにします。
参考: Hybrid Networking using VPC Endpoints (AWS PrivateLink) and Amazon CloudWatch for Financial Services
オンプレミスからの VPC Endpoint 名前解決(Route 53 Resolver)
Direct Connect で VPC に接続しているオンプレミスサーバ(オンプレミスサーバやネットワーク機器)が、monitoring.ap-northeast-1.amazonaws.com などの VPC Endpoint DNS 名を解決できるように、Route 53 Resolver インバウンドエンドポイントを VPC 内に作成します。
DNS 解決フロー
[オンプレミス DNS サーバ]
転送ルール: *.amazonaws.com → Route 53 Resolver インバウンドエンドポイントの IP
↓(Direct Connect 経由)
[Route 53 Resolver インバウンドエンドポイント(VPC 内)]
↓
[VPC Endpoint のプライベート DNS(10.x.x.x)を返答]
↓
[CloudWatch Agent / ネットワーク機器が VPC Endpoint のプライベート IP に直接通信]
ソースアカウントに CloudFormation テンプレートを展開します。
パラメータ AllowedSourceCidr にはオンプレミス DNS サーバのIPアドレスを含む CIDR を入力します。
# route53-resolver.yaml (deploy in each source account)
AWSTemplateFormatVersion: '2010-09-09'
Description: Route 53 Resolver Inbound Endpoint for on-premises DNS forwarding
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
SubnetId1:
Type: AWS::EC2::Subnet::Id
Description: Subnet for inbound endpoint (AZ1)
SubnetId2:
Type: AWS::EC2::Subnet::Id
Description: Subnet for inbound endpoint (AZ2)
AllowedSourceCidr:
Type: String
Description: CIDR block of on-premises DNS servers allowed to query the inbound endpoint
Resources:
ResolverEndpointSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: route53-resolver-inbound-sg
GroupDescription: Allow inbound DNS queries to the Route 53 Resolver inbound endpoint
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 53
ToPort: 53
CidrIp: !Ref AllowedSourceCidr
- IpProtocol: udp
FromPort: 53
ToPort: 53
CidrIp: !Ref AllowedSourceCidr
SecurityGroupEgress:
- IpProtocol: -1
CidrIp: 0.0.0.0/0
R53InboundResolver:
Type: AWS::Route53Resolver::ResolverEndpoint
Properties:
Name: onprem-dns-inbound
Direction: INBOUND
IpAddresses:
- SubnetId: !Ref SubnetId1
- SubnetId: !Ref SubnetId2
SecurityGroupIds:
- !Ref ResolverEndpointSecurityGroup
Outputs:
ResolverEndpointArn:
Value: !GetAtt R53InboundResolver.Arn
Description: Resolver endpoint ARN (check assigned IPs in console or API)
ResolverSecurityGroupId:
Value: !Ref ResolverEndpointSecurityGroup
Description: Security group ID attached to the Route 53 Resolver inbound endpoint
インバウンドエンドポイントを作成したら、マネジメントコンソールで割り当てられた 2 つの IP アドレスを確認し、オンプレミスの DNS サーバ(Windows DNS や BIND 等)に以下の転送ルールを設定します。
# BIND (named.conf) example
zone "amazonaws.com" {
type forward;
forwarders {
10.x.x.x; # Route 53 Resolver インバウンドエンドポイント IP (AZ-a)
10.x.x.y; # Route 53 Resolver インバウンドエンドポイント IP (AZ-c)
};
};
5. サーバ監視の実装
監視項目と収集方法の例(EC2 / オンプレミスサーバ)
| 監視項目 | 対象リソース | メトリクス / ログ名 | 収集方法 |
|---|---|---|---|
| 死活 | EC2 | StatusCheckFailed |
CloudWatch 標準 |
| 死活 | ALB | HealthyHostCount |
CloudWatch 標準 |
| 死活 | NLB | HealthyHostCount |
CloudWatch 標準 |
| CPU 使用率 | EC2 | CPUUtilization |
CloudWatch 標準 |
| CPU 使用率 | オンプレミス | Linux: CWAgent/cpu_usage_activeWindows: CWAgent/Processor % Processor Time
|
CloudWatch Agent |
| メモリ使用率 | EC2 / オンプレミス | Linux: CWAgent/mem_used_percentWindows: CWAgent/Memory % Committed Bytes In Use
|
CloudWatch Agent |
| ディスク使用率 | EC2 / オンプレミス | Linux: CWAgent/disk_used_percentWindows: CWAgent/LogicalDisk % Free Space
|
CloudWatch Agent |
| Windows イベントログ | EC2 / オンプレミス | CloudWatch Logs | CloudWatch Agent |
| テキストログ | EC2 / オンプレミス | CloudWatch Logs | CloudWatch Agent |
| サービス / プロセス監視 | EC2 / オンプレミス | Linux: CWAgent/procstat/cpu_usageWindows: CWAgent/Process(*) % Processor Time
|
CloudWatch Agent |
メモリ・ディスク使用率はEC2 インスタンスの CloudWatch 標準メトリクスに含まれません。
EC2 インスタンスにも CloudWatch Agent のインストールが必要です。
CloudWatch メトリクス / ログ 送信用 VPC Endpointの作成
EC2 とオンプレミスサーバ(Direct Connect 経由の CloudWatch Agent)から、CloudWatch メトリクスと CloudWatch Logs へ閉域で送信するため、ソースアカウントに CloudFormation テンプレートを展開し、VPC Interface Endpoint を作成します。
パラメータ AllowedSourceCidr にはオンプレミスサーバやネットワーク機器のIPアドレスを含む CIDR を入力します。
VPC 内に対象の Endpoint が作成済みの場合はエラーとなります。
作成済みの場合は本手順はスキップしてください。
# server-monitoring-vpc-endpoints.yaml (deploy in each source account)
AWSTemplateFormatVersion: '2010-09-09'
Description: VPC Interface Endpoints for CloudWatch metrics and logs
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
SubnetIds:
Type: List<AWS::EC2::Subnet::Id>
Description: Subnets for VPC Interface Endpoints (multi-AZ recommended)
AllowedSourceCidr:
Type: String
Description: Source CIDR allowed to send HTTPS traffic to endpoints (for example 10.0.0.0/16)
Resources:
MonitoringLogsEndpointSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: cloudwatch-monitoring-logs-vpce-sg
GroupDescription: Allow HTTPS traffic to CloudWatch monitoring and logs VPC endpoints
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: !Ref AllowedSourceCidr
SecurityGroupEgress:
- IpProtocol: -1
CidrIp: 0.0.0.0/0
VPCEndpointMonitoring:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VpcId
VpcEndpointType: Interface
ServiceName: !Sub "com.amazonaws.${AWS::Region}.monitoring"
SubnetIds: !Ref SubnetIds
SecurityGroupIds:
- !Ref MonitoringLogsEndpointSecurityGroup
PrivateDnsEnabled: true
VPCEndpointLogs:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VpcId
VpcEndpointType: Interface
ServiceName: !Sub "com.amazonaws.${AWS::Region}.logs"
SubnetIds: !Ref SubnetIds
SecurityGroupIds:
- !Ref MonitoringLogsEndpointSecurityGroup
PrivateDnsEnabled: true
Outputs:
MonitoringVPCEndpointId:
Value: !Ref VPCEndpointMonitoring
Description: VPC Interface Endpoint ID for CloudWatch metrics
LogsVPCEndpointId:
Value: !Ref VPCEndpointLogs
Description: VPC Interface Endpoint ID for CloudWatch Logs
MonitoringLogsEndpointSecurityGroupId:
Value: !Ref MonitoringLogsEndpointSecurityGroup
Description: Security group ID attached to both endpoints
オンプレミスサーバ監視の実装
オンプレミスサーバを監視する場合は、上記 2 つの VPC Endpoint(monitoring / logs)に加え、4 章の Route 53 Resolver インバウンドエンドポイント設定とオンプレミス DNS 転送設定が必要です。
CloudWatch Agent は Direct Connect 経由で VPC Endpoint のプライベート IP に到達し、インターネットを経由せずにメトリクスやログを送信します。
オンプレミスサーバ上の CloudWatch Agent の設定は複数パターンが存在するため、本記事では記載は省略します。
AWS ドキュメントで案内されている実装例を参照し設定してください。
参考: Install the CloudWatch agent on on-premises servers
参考: Configure on-premises servers that use SSM Agent and unified CloudWatch Agent to use only temporary credentials
参考: Installing the CloudWatch agent using Systems Manager(on-premises considerations)
参考: Starting the CloudWatch agent on an on-premises server(SSM Agent 利用)
6. ネットワーク機器監視の実装
監視項目と収集方法(ネットワーク機器)
| 監視項目 | 収集方法 | 送信先 |
|---|---|---|
| 死活 | Network Synthetic Monitor(VPC サブネットから ICMP プローブ送信) | CloudWatch メトリクス |
| SNMP | CloudWatch のマネージド機能では直接サポートされない(別途連携設計が必要) | 要件に応じて設計 |
| SNMPTrap | CloudWatch のマネージド機能では直接サポートされない(別途連携設計が必要) | 要件に応じて設計 |
| Syslog | VPC Endpoint (syslog-logs) に直接送信(🆕 2026年6月新機能) | CloudWatch Logs |
死活監視:Network Synthetic Monitor
AWS マネージドサービスである Network Synthetic Monitor(Amazon CloudWatch のネットワーク監視機能) を使用して、VPC サブネットからオンプレミスのネットワーク機器に ICMP プローブを送信します。
仕組み
[VPC サブネット(AWS マネージドプローブ送信元)]
↓ ICMP probe
[Direct Connect]
↓
[ネットワーク機器の IP アドレス]
→ RTT / PacketLoss メトリクス → CloudWatch
出力メトリクス
| メトリクス名 | 内容 |
|---|---|
RTT |
往復遅延(ミリ秒) |
PacketLoss |
パケットロス率(%) |
NetworkHealthIndicator |
Direct Connect 経由の場合のみ。AWS 側ネットワーク健全性(0 or 1) |
設定手順
ソースアカウントに対して CLI を実行し、Network Synthetic Monitor を設定します。
CloudFormation 非対応(2026-08-08 時点) — CLI で作成します。
下記コマンドの AWS アカウント ID、サブネット ID、IP アドレス はサンプル値です。実行前に必ず自環境の値へ修正してから実行してください。
# Step 1: 監視対象を束ねるモニターを作成
aws networkmonitor create-monitor \
--monitor-name "network-device-monitor" \
--aggregation-period 30 \
--region ap-northeast-1
# Step 2: 監視するネットワーク機器ごとにプローブを追加
# 例: 機器1 (10.0.0.1) への ICMP プローブ
aws networkmonitor create-probe \
--monitor-name "network-device-monitor" \
--probe '{
"sourceArn": "arn:aws:ec2:ap-northeast-1:111111111111:subnet/subnet-xxxxxxxxx",
"destination": "10.0.0.1",
"protocol": "ICMP",
"packetSize": 56
}' \
--region ap-northeast-1
# 例: 機器2 (10.0.0.2) への ICMP プローブ
aws networkmonitor create-probe \
--monitor-name "network-device-monitor" \
--probe '{
"sourceArn": "arn:aws:ec2:ap-northeast-1:111111111111:subnet/subnet-xxxxxxxxx",
"destination": "10.0.0.2",
"protocol": "ICMP",
"packetSize": 56
}' \
--region ap-northeast-1
CloudWatch アラームの設定
Network Synthetic Monitor が発行するメトリクスは、OAM により集約アカウント側でクロスアカウントアラームとして設定できます。
集約アカウントに CloudFormation テンプレートを展開します。
上記で作成した ICMP プローブのID を ProbeId パラメータへ入力します。
# network-monitor-alarms.yaml (deploy in monitoring account)
AWSTemplateFormatVersion: '2010-09-09'
Description: Cross-account alarms for Network Synthetic Monitor probes
Parameters:
SourceAccountId:
Type: String
Description: Source account ID where Network Synthetic Monitor was created
MonitorName:
Type: String
Default: network-device-monitor
ProbeId:
Type: String
Description: Probe ID returned by create-probe
AlertTopicArn:
Type: String
Resources:
# Packet loss alarm for network device health
CrossAcctFirewallPacketLossAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: !Sub "${SourceAccountId}-${MonitorName}-${ProbeId}-PacketLoss"
AlarmDescription: !Sub "ICMP packet loss threshold exceeded in source account ${SourceAccountId}"
Metrics:
- Id: m1
AccountId: !Ref SourceAccountId
MetricStat:
Metric:
Namespace: AWS/NetworkMonitor
MetricName: PacketLoss
Dimensions:
- Name: Monitor
Value: !Ref MonitorName
- Name: Probe
Value: !Ref ProbeId
Period: 60
Stat: Average
ReturnData: true
EvaluationPeriods: 3
Threshold: 10 # Alarm when packet loss exceeds 10%
ComparisonOperator: GreaterThanOrEqualToThreshold
AlarmActions:
- !Ref AlertTopicArn
TreatMissingData: breaching # Treat missing probe data as a failure
TreatMissingData: breaching を設定する理由
ネットワーク機器が完全停止すると、プローブ自体が届かなくなりメトリクスが欠損します。breaching にすることで、データ欠損をアラーム状態として検知できます。
Syslog 監視:CloudWatch Logs Syslog Ingestion
🆕 2026年6月リリースの新機能
Amazon CloudWatch Logs manages syslog ingestion — AWS What's New
従来は Syslog 収集サーバ(EC2)を中継する必要がありましたが、CloudWatch Logs Syslog Ingestion により、ネットワーク機器から VPC Endpoint へエージェント不要で直接送信できるようになりました。
対応プロトコル・フォーマット
| 項目 | 対応内容 |
|---|---|
| 通信プロトコル | TCP、TCP+TLS、UDP |
| Syslog フォーマット | RFC 5424、RFC 3164、Cisco FTD/ASA |
| 自動抽出フィールド | facility、severity、hostname、application name |
設定手順
ソースアカウントに CloudFormation テンプレートを展開し、VPC Interface Endpoint を作成します。
パラメータ AllowedSourceCidr にはネットワーク機器のIPアドレスを含む CIDR を入力します。
# syslog-ingestion-endpoint.yaml (deploy in each source account)
AWSTemplateFormatVersion: '2010-09-09'
Description: Syslog ingestion endpoint resources
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
SubnetIds:
Type: List<AWS::EC2::Subnet::Id>
Description: "Subnets for VPC Interface Endpoint (multi-AZ recommended)"
AllowedSourceCidr:
Type: String
Description: "Source CIDR allowed to send syslog traffic (for example 10.0.0.0/16)"
Resources:
# Create a security group
SyslogEndpointSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: syslog-vpce-sg
GroupDescription: Allow syslog traffic to VPC endpoint
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 6514
ToPort: 6514
CidrIp: !Ref AllowedSourceCidr
- IpProtocol: tcp
FromPort: 1514
ToPort: 1514
CidrIp: !Ref AllowedSourceCidr
- IpProtocol: udp
FromPort: 514
ToPort: 514
CidrIp: !Ref AllowedSourceCidr
SecurityGroupEgress:
- IpProtocol: -1
CidrIp: 0.0.0.0/0
# Create the VPC endpoint
VPCEndpointSyslogLogs:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VpcId
VpcEndpointType: Interface
ServiceName: !Sub "com.amazonaws.${AWS::Region}.syslog-logs"
SubnetIds: !Ref SubnetIds
SecurityGroupIds:
- !Ref SyslogEndpointSecurityGroup
PrivateDnsEnabled: true
# Create a log group
SyslogLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: /syslog/network-devices
RetentionInDays: 90
# Add a resource policy
SyslogResourcePolicy:
Type: AWS::Logs::ResourcePolicy
Properties:
PolicyName: SyslogIngestionResourcePolicy
PolicyDocument: !Sub |
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSyslogServiceToWrite",
"Effect": "Allow",
"Principal": {
"Service": "syslog.logs.amazonaws.com"
},
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "${SyslogLogGroup.Arn}:*",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "${AWS::AccountId}"
},
"ArnEquals": {
"aws:SourceArn": "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc-endpoint/${VPCEndpointSyslogLogs}"
}
}
}
]
}
Outputs:
SyslogVPCEndpointId:
Value: !Ref VPCEndpointSyslogLogs
Export:
Name: !Sub "${AWS::StackName}-SyslogVPCEndpointId"
SyslogLogGroupArn:
Value: !GetAtt SyslogLogGroup.Arn
Export:
Name: !Sub "${AWS::StackName}-SyslogLogGroupArn"
SyslogEndpointSecurityGroupId:
Value: !Ref SyslogEndpointSecurityGroup
Export:
Name: !Sub "${AWS::StackName}-SyslogEndpointSecurityGroupId"
PutSyslogConfiguration は CloudFormation 非対応(2026-08-08 時点) — CLI で作成します。
VPC Endpoint・セキュリティグループ・ロググループ・リソースポリシーまでは CloudFormation で作成し、Syslog 関連付け(put-syslog-configuration)のみ CLI で設定します。
スタック展開後、上記で作成した SyslogVPCEndpointId に $VPCE_ID を置き換えて、1 度だけ実行してください。
# Syslog 取り込み設定を作成
aws logs put-syslog-configuration \
--log-group-identifier /syslog/network-devices \
--vpc-endpoint-id $VPCE_ID \
--region ap-northeast-1
# Syslog 取り込み設定確認
aws logs list-syslog-configurations \
--region ap-northeast-1
ネットワーク機器側の設定(DNS 名指定推奨)
設定内容は機種やファームウェアにより差異があるため、ご利用中の機器のマニュアルをご確認ください。
Syslog の送信先は、VPC Endpoint の DNS 名(FQDN)で指定することを推奨します。
運用要件により、VPC Interface Endpoint のプライベート IP を直接指定する構成も可能です。
VPC Endpoint の DNS 名は、ネットワーク機器が参照する DNS サーバが Route 53 Resolver 経由で解決できるよう設定してください。
参考: Syslog ingestion - AWS ドキュメント
参考: Setting up syslog ingestion
SNMP / SNMPTrap 監視について
AWS CloudWatch のマネージド機能では、SNMP および SNMPTrap は直接サポートされていません。
そのため、SNMP 関連の監視を要件に含める場合は、別途連携方式を設計してください(本記事では具体的な実装手順は省略します)。
7. メンテナンス通知の管理(Alarm Mute Rules)
🆕 2026年1月リリースの新機能
Amazon CloudWatch Alarm Mute Rules — AWS What's New
メンテナンス時などの不要なアラーム通知を抑止する専用機能として、Alarm Mute Rules が 2026 年 1 月にリリースされました。
以前はスケジューラと組み合わせて無効化・有効化する必要がありましたが、この機能ではスケジュールを含めて設定できます。
また、ミュートルールのスケジュール終了時に ALARM 状態のままであれば、アクションが自動実行されます。
Alarm Mute Rules の仕様
| 項目 | 仕様 |
|---|---|
| スケジュール形式 | Cron 式(繰り返し)または At 式(1回限り) |
| 1 ルール当たりの最大対象アラーム数 | 100 個 |
| ミュート持続時間 | 最短 1 分(PT1M)〜 最長 15 日(P15D) |
| タイムゾーン指定 | 対応(例: Asia/Tokyo) |
| ミュート後の動作 | ルール終了時に ALARM 状態のままならアクションを自動実行 |
| 適用状態 | OK、ALARM、INSUFFICIENT_DATA |
設定例
集約アカウントに CloudFormation テンプレートを展開し、ミュートルールを作成します。
パラメータ MuteTargetAlarmNames にミュートする対象のアラーム名をカンマ区切りで入力します。
# alarm-mute-rules.yaml (deploy in monitoring account)
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudWatch Alarm Mute Rules for maintenance windows
Parameters:
MuteTargetAlarmNames:
Type: CommaDelimitedList
Description: "Comma-separated CloudWatch alarm names to mute (for example alarm-a,alarm-b)"
MuteRuleName:
Type: String
Default: weekly-maintenance-sunday
Description: "Rule name for the mute rule"
MuteExpression:
Type: String
Default: "cron(0 2 * * SUN)"
Description: "Schedule expression for mute rule (cron(...) or at(...))"
MuteDuration:
Type: String
Default: PT4H
Description: "Mute duration for rule"
MuteDescription:
Type: String
Default: Mute notifications during the configured maintenance window.
Description: "Description for the mute rule purpose"
Resources:
AlarmMuteRule:
Type: AWS::CloudWatch::AlarmMuteRule
Properties:
Name: !Ref MuteRuleName
Description: !Ref MuteDescription
Rule:
Schedule:
Expression: !Ref MuteExpression
Duration: !Ref MuteDuration
Timezone: Asia/Tokyo
MuteTargets:
AlarmNames: !Ref MuteTargetAlarmNames
本テンプレートを別のスタックとして作成することで、定期メンテナンス(Cron)や臨時メンテナンス(At)を作成できます。
1 ルールあたり最大 100 アラームの制限があります。
対象アラームが 100 を超える場合は複数のミュートルールに分割してください(後述のクォータ一覧参照)。
8. AI 駆動の運用効率化(AWS DevOps Agent)
OAM と組み合わせる理由
AWS DevOps Agent は、Agent Space を単位として複数 AWS アカウントへアクセスし、障害調査を自律的に実行できる運用支援サービスです。
| CloudWatch + OAM | AWS DevOps Agent | |
|---|---|---|
| 主目的 | アラート検知と横断可視化 | 横断調査と運用支援 |
| 強み | 低遅延の閾値検知、統合ダッシュボード | 複数アカウント横断での自律的な原因調査 |
| マルチアカウント設計 | OAM Link/Sink | Agent Space + AssumeRole |
| 閉域対応 | PrivateLink + Route 53 Resolver | PrivateLink |
OAM を観測データ統合の基盤として固定し、障害解析フェーズを DevOps Agent で標準化する、二層構成です。
DevOps Agent のマルチアカウント処理フロー
[集約アカウント]
├─ OAM Sink(可観測性データの集約窓口)
└─ DevOps Agent Agent Space(運用オーケストレーション)
↓ AssumeRole
[ソースアカウント A/B/C ...]
├─ DevOpsAgentRole(AIDevOpsAgentAccessPolicy 付与)
└─ OAM Link(メトリクス/ログ共有)
Step 1: Agent Space を作成
集約アカウントに CloudFormation テンプレートを展開します。
# devops-agent-space.yaml (deploy in monitoring account)
AWSTemplateFormatVersion: '2010-09-09'
Description: AWS DevOps Agent Space for multi-account operations
Resources:
# IAM role for DevOps Agent Web App (Operator App)
DevOpsOperatorRole:
Type: AWS::IAM::Role
Properties:
RoleName: DevOpsAgentRole-WebappAdmin
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: aidevops.amazonaws.com
Action:
- sts:AssumeRole
- sts:TagSession
Condition:
StringEquals:
aws:SourceAccount: !Ref AWS::AccountId
ArnLike:
aws:SourceArn: !Sub arn:aws:aidevops:${AWS::Region}:${AWS::AccountId}:agentspace/*
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AIDevOpsOperatorAppAccessPolicy
OpsAgentSpace:
Type: AWS::DevOpsAgent::AgentSpace
Properties:
Name: central-monitoring-agent-space
Description: Agent Space for OAM-based multi-account monitoring operations
Locale: ja-JP
OperatorApp:
Iam:
OperatorAppRoleArn: !GetAtt DevOpsOperatorRole.Arn
Outputs:
AgentSpaceId:
Value: !GetAtt OpsAgentSpace.AgentSpaceId
OperatorAppRoleArn:
Value: !GetAtt DevOpsOperatorRole.Arn
Step 2: ソースアカウント側 IAM ロールを作成
各ソースアカウントで DevOps Agent から引き受け可能なロールを作成します。
信頼ポリシーの aws:SourceAccount / aws:SourceArn 条件と、追加のインラインポリシーを設定します。
各ソースアカウントに CloudFormation テンプレートを展開します。
集約アカウントの AWS アカウントIDと Step 1 で作成した AgentSpaceId をパラメータへ入力します。
# source-account-devopsagent-role.yaml (deploy in each source account)
AWSTemplateFormatVersion: '2010-09-09'
Description: Role for AWS DevOps Agent cross-account investigation
Parameters:
MonitoringAccountId:
Type: String
Description: 12-digit monitoring account ID that hosts the Agent Space
AgentSpaceId:
Type: String
Description: Agent Space ID created in the monitoring account
Resources:
DevOpsAgentRole:
Type: AWS::IAM::Role
Properties:
RoleName: DevOpsAgentRole-AgentSpace
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: aidevops.amazonaws.com
Action: sts:AssumeRole
Condition:
StringEquals:
aws:SourceAccount: !Ref MonitoringAccountId
aws:SourceArn: !Sub 'arn:aws:aidevops:${AWS::Region}:${MonitoringAccountId}:agentspace/${AgentSpaceId}'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AIDevOpsAgentAccessPolicy
Policies:
- PolicyName: AIDevOpsAllowAwsSupportActionsPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: AllowCreateServiceLinkedRoles
Effect: Allow
Action:
- iam:CreateServiceLinkedRole
Resource:
- !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/resource-explorer-2.amazonaws.com/AWSServiceRoleForResourceExplorer
Step 3: AWS アカウントを関連付け(Association)
AWS::DevOpsAgent::Association を使って、まず集約アカウント(monitor)を関連付け、必要に応じて各ソースアカウント(source)を追加します。集約アカウントに CloudFormation テンプレートを展開してください。
パラメータ SourceAccountIds に集約対象の AWS アカウントIDをカンマ区切りで入力します。
# devops-agent-associations.yaml (deploy in monitoring account)
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::LanguageExtensions'
Description: Associate monitor/source AWS accounts to DevOps Agent Space
Parameters:
AgentSpaceId:
Type: String
SourceAccountIds:
Type: CommaDelimitedList
Description: Comma-separated list of 12-digit source account IDs
SourceRoleName:
Type: String
Default: DevOpsAgentRole-AgentSpace
Description: Role name that DevOps Agent assumes in source accounts
Resources:
DevOpsAgentRoleAgentSpace:
Type: AWS::IAM::Role
Properties:
RoleName: DevOpsAgentRole-AgentSpace
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: aidevops.amazonaws.com
Action: sts:AssumeRole
Condition:
StringEquals:
aws:SourceAccount: !Ref AWS::AccountId
ArnLike:
aws:SourceArn: !Sub arn:aws:aidevops:${AWS::Region}:${AWS::AccountId}:agentspace/*
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AIDevOpsAgentAccessPolicy
Policies:
- PolicyName: AIDevOpsAllowAwsSupportActionsPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: AllowCreateServiceLinkedRoles
Effect: Allow
Action:
- iam:CreateServiceLinkedRole
Resource:
- !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/resource-explorer-2.amazonaws.com/AWSServiceRoleForResourceExplorer
MonitorAwsAssociation:
Type: AWS::DevOpsAgent::Association
Properties:
AgentSpaceId: !Ref AgentSpaceId
ServiceId: aws
Configuration:
Aws:
AccountId: !Ref AWS::AccountId
AccountType: monitor
AssumableRoleArn: !GetAtt DevOpsAgentRoleAgentSpace.Arn
'Fn::ForEach::SourceAwsAssociations':
- SourceAccountId
- !Ref SourceAccountIds
- 'SourceAwsAssociation${SourceAccountId}':
Type: AWS::DevOpsAgent::Association
DependsOn: MonitorAwsAssociation
Properties:
AgentSpaceId: !Ref AgentSpaceId
ServiceId: aws
Configuration:
SourceAws:
AccountId: !Sub '${SourceAccountId}'
AccountType: source
AssumableRoleArn: !Sub 'arn:aws:iam::${SourceAccountId}:role/${SourceRoleName}'
上記の Fn::ForEach 例は、ソースアカウント側のロール名が共通(例: DevOpsAgentRole-AgentSpace)である前提です。
アカウントごとにロール ARN が異なる場合は、個別の Association 定義で作成してください。
OAM 前提での運用パターン(複数アカウント管理)
- CloudWatch アラーム発報(集約アカウント)
- OAM を経由して対象アカウントのメトリクスやログを横断確認
- DevOps Agent を同一 Agent Space から実行し、関連アカウント横断で原因調査
- 調査結果に基づき、運用手順書(Runbook)に沿って手動または自動対応
OAM で監視可視化を集約し、DevOps Agent で調査を集中することで、大量アカウント環境でもインシデント対応の負荷を下げられます。
アラーム起点で DevOps Agent に自律調査させる手順
これは、閉域通信に必要な VPC Endpoint 構築と、CloudWatch アラーム起点の自律調査起動のための手順です。
[CloudWatch Alarm]
↓
[EventBridge Rule]
↓
[Lambda(VPC 内)]
↓
[DevOps Agent Webhook(event-ai VPC Endpoint)]
本構成(CloudWatch アラーム起点で Webhook を呼び出す経路)で必須のエンドポイントは以下です。
-
com.amazonaws.{region}.secretsmanager(Webhook シークレット参照) -
com.amazonaws.{region}.event-ai(Webhook Events)
Step 1: DevOps Agent 用 VPC Endpoint を作成
集約アカウントに CloudFormation テンプレートを展開します。
パラメータ AllowedSourceCidr には VPC の CIDR を入力します。
# devops-agent-event-ai-vpc-endpoint.yaml (deploy in monitoring account)
AWSTemplateFormatVersion: '2010-09-09'
Description: VPC Interface Endpoints for DevOps Agent webhook (event-ai) and Secrets Manager
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
SubnetIds:
Type: List<AWS::EC2::Subnet::Id>
Description: Subnets for VPC Interface Endpoint (multi-AZ recommended)
AllowedSourceCidr:
Type: String
Description: Source CIDR allowed to send HTTPS traffic to endpoint (for example 10.0.0.0/16)
Resources:
# Security group for event-ai VPC Interface Endpoint
EventAIEndpointSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: devops-agent-event-ai-vpce-sg
GroupDescription: Allow HTTPS traffic from Lambda subnet range to event-ai endpoint
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: !Ref AllowedSourceCidr
SecurityGroupEgress:
- IpProtocol: -1
CidrIp: 0.0.0.0/0
# DevOps Agent Webhook endpoint
VPCEndpointEventAI:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VpcId
VpcEndpointType: Interface
ServiceName: !Sub "com.amazonaws.${AWS::Region}.event-ai"
SubnetIds: !Ref SubnetIds
SecurityGroupIds:
- !Ref EventAIEndpointSecurityGroup
PrivateDnsEnabled: true
# Secrets Manager endpoint for Lambda secret retrieval in private subnets
VPCEndpointSecretsManager:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VpcId
VpcEndpointType: Interface
ServiceName: !Sub "com.amazonaws.${AWS::Region}.secretsmanager"
SubnetIds: !Ref SubnetIds
SecurityGroupIds:
- !Ref EventAIEndpointSecurityGroup
PrivateDnsEnabled: true
Outputs:
EventAIVPCEndpointId:
Value: !Ref VPCEndpointEventAI
Description: VPC Interface Endpoint ID for DevOps Agent webhook events
SecretsManagerVPCEndpointId:
Value: !Ref VPCEndpointSecretsManager
Description: VPC Interface Endpoint ID for Secrets Manager access from Lambda
EventAIEndpointSecurityGroupId:
Value: !Ref EventAIEndpointSecurityGroup
Description: Security group ID attached to event-ai endpoint
Step 2: EventBridge + Lambda を作成
ALARM 遷移イベントを受信して Lambda から Webhook を呼び出す構成を作成するため、集約アカウントに CloudFormation テンプレートを展開します。
パラメータ AllowedSourceCidr には VPC の CIDR を入力します。
ResourcePrefix は任意です。
# devops-agent-alarm-pipeline.yaml (deploy in monitoring account)
AWSTemplateFormatVersion: '2010-09-09'
Description: Trigger DevOps Agent webhook from CloudWatch alarm via EventBridge and Lambda
Parameters:
ResourcePrefix:
Type: String
Default: devops-agent
Description: Prefix for resource names
VpcId:
Type: AWS::EC2::VPC::Id
Description: VPC ID where Lambda and endpoints are deployed
LambdaSubnetIds:
Type: List<AWS::EC2::Subnet::Id>
Description: Private subnets for Lambda
AllowedSourceCidr:
Type: String
Description: Source CIDR allowed to send HTTPS traffic to endpoint SG (for example 10.0.0.0/16)
Resources:
DevOpsAgentWebhookSecret:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Sub '${ResourcePrefix}-webhook-credentials'
Description: DevOps Agent webhook URL and HMAC secret
SecretString: '{"DEVOPS_AGENT_WEBHOOK_URL":"","DEVOPS_AGENT_WEBHOOK_SECRET":""}'
Tags:
- Key: Name
Value: !Sub '${ResourcePrefix}-Webhook-Credentials'
WebhookDLQ:
Type: AWS::SQS::Queue
Properties:
QueueName: !Sub '${ResourcePrefix}-Webhook-DLQ'
SqsManagedSseEnabled: true
MessageRetentionPeriod: 1209600
Tags:
- Key: Name
Value: !Sub '${ResourcePrefix}-Webhook-DLQ'
DevOpsAgentWebhookLambdaSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub '${ResourcePrefix}-Webhook-Lambda-SG'
GroupDescription: Security group attached to DevOps Agent webhook Lambda
VpcId: !Ref VpcId
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: !Ref AllowedSourceCidr
Tags:
- Key: Name
Value: !Sub '${ResourcePrefix}-Webhook-Lambda-SG'
DevOpsAgentWebhookRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub '${ResourcePrefix}-Webhook-Role'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
- arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
Policies:
- PolicyName: SecretsManagerAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource: !Ref DevOpsAgentWebhookSecret
- Effect: Allow
Action:
- sqs:SendMessage
Resource: !GetAtt WebhookDLQ.Arn
Tags:
- Key: Name
Value: !Sub '${ResourcePrefix}-Webhook-Role'
DevOpsAgentWebhookFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: !Sub '${ResourcePrefix}-DevOpsAgent-Webhook'
Runtime: python3.13
Handler: index.lambda_handler
Role: !GetAtt DevOpsAgentWebhookRole.Arn
Timeout: 30
ReservedConcurrentExecutions: 10
DeadLetterConfig:
TargetArn: !GetAtt WebhookDLQ.Arn
VpcConfig:
SubnetIds: !Ref LambdaSubnetIds
SecurityGroupIds:
- !Ref DevOpsAgentWebhookLambdaSecurityGroup
Environment:
Variables:
SECRET_ARN: !Ref DevOpsAgentWebhookSecret
Code:
ZipFile: |
import json
import os
import urllib3
import hmac
import hashlib
import base64
import boto3
from datetime import datetime
http = urllib3.PoolManager()
secrets_client = boto3.client('secretsmanager')
def get_webhook_credentials():
secret_arn = os.environ['SECRET_ARN']
response = secrets_client.get_secret_value(SecretId=secret_arn)
return json.loads(response['SecretString'])
def _find_account_id(obj):
# CloudWatch Alarm State Change の configuration.metrics などを再帰探索して accountId を抽出
if isinstance(obj, dict):
for key in ('accountId', 'AccountId'):
value = obj.get(key)
if isinstance(value, str) and value.isdigit() and len(value) == 12:
return value
for value in obj.values():
found = _find_account_id(value)
if found:
return found
elif isinstance(obj, list):
for item in obj:
found = _find_account_id(item)
if found:
return found
return None
def lambda_handler(event, context):
print(f"Received event: {json.dumps(event)}")
detail = event.get('detail', {})
alarm_name = detail.get('alarmName', 'UnknownAlarm')
alarm_description = detail.get('configuration', {}).get('description', 'No description')
state = detail.get('state', {})
new_state = state.get('value', 'UNKNOWN')
reason = state.get('reason', 'No reason provided')
timestamp = state.get('timestamp', datetime.utcnow().isoformat())
region = event.get('region', os.environ.get('AWS_REGION', 'us-east-1'))
monitoring_account_id = event.get('account', 'unknown')
# OAM のクロスアカウントメトリクスに紐づく Alarm イベントから対象アカウント ID を推定
target_account_id = _find_account_id(detail.get('configuration', {}))
if not target_account_id:
target_account_id = monitoring_account_id
if new_state != 'ALARM':
print(f"Alarm state is {new_state}, not triggering investigation")
return {'statusCode': 200, 'body': 'Alarm not in ALARM state'}
credentials = get_webhook_credentials()
webhook_url = credentials['DEVOPS_AGENT_WEBHOOK_URL']
webhook_secret = credentials['DEVOPS_AGENT_WEBHOOK_SECRET']
if not webhook_url or not webhook_secret:
print("Webhook credentials not configured yet")
return {'statusCode': 200, 'body': 'Webhook credentials not configured'}
payload = {
'eventType': 'incident',
'incidentId': f"{alarm_name}-{int(datetime.utcnow().timestamp())}",
'action': 'created',
'priority': 'HIGH',
'title': f"CloudWatch Alarm: {alarm_name}",
'description': f"{alarm_description}\n\nReason: {reason}\nMonitoringAccountId: {monitoring_account_id}\nTargetAccountId: {target_account_id}",
'timestamp': timestamp,
'service': alarm_name,
'data': {
'metadata': {
'region': region,
'environment': 'oam-cross-account-monitoring',
'monitoringAccountId': monitoring_account_id,
'targetAccountId': target_account_id,
'alarmName': alarm_name,
'alarmState': new_state
}
}
}
payload_str = json.dumps(payload)
timestamp_str = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.000Z')
message = f"{timestamp_str}:{payload_str}"
signature = base64.b64encode(
hmac.new(
webhook_secret.encode('utf-8'),
message.encode('utf-8'),
hashlib.sha256
).digest()
).decode('utf-8')
headers = {
'Content-Type': 'application/json',
'x-amzn-event-timestamp': timestamp_str,
'x-amzn-event-signature': signature
}
try:
response = http.request(
'POST',
webhook_url,
body=payload_str,
headers=headers
)
print(f"Webhook response: {response.status} - {response.data.decode('utf-8')}")
return {
'statusCode': 200,
'body': json.dumps({
'message': 'DevOps Agent investigation triggered',
'alarmName': alarm_name,
'webhookStatus': response.status,
'targetAccountId': target_account_id
})
}
except Exception as e:
print(f"Error calling webhook: {str(e)}")
return {
'statusCode': 500,
'body': json.dumps({'error': str(e)})
}
WebhookEventBridgeRule:
Type: AWS::Events::Rule
Properties:
Name: !Sub '${ResourcePrefix}-EventBridge-Rule'
State: ENABLED
EventPattern:
source:
- aws.cloudwatch
detail-type:
- CloudWatch Alarm State Change
detail:
state:
value:
- ALARM
Targets:
- Id: DevOpsAlarmWebhookLambdaTarget
Arn: !GetAtt DevOpsAgentWebhookFunction.Arn
WebhookFunctionPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref DevOpsAgentWebhookFunction
Action: lambda:InvokeFunction
Principal: events.amazonaws.com
SourceArn: !GetAtt WebhookEventBridgeRule.Arn
このテンプレートの WebhookEventBridgeRule は、alarmName 条件を指定していないため、対象リージョン内で ALARM に遷移した CloudWatch アラーム全般を対象にします。特定の複数アラームだけに限定したい場合は、EventPattern.detail.alarmName に対象アラーム名を列挙してください。
複数アラーム名をパラメータで受けて対象を限定したい場合は、例えば以下のように CommaDelimitedList パラメータを追加できます。
Parameters:
TargetAlarmNames:
Type: CommaDelimitedList
Description: Comma-separated CloudWatch alarm names to trigger DevOps Agent
Resources:
WebhookEventBridgeRule:
Type: AWS::Events::Rule
Properties:
Name: !Sub '${ResourcePrefix}-EventBridge-Rule'
State: ENABLED
EventPattern:
source:
- aws.cloudwatch
detail-type:
- CloudWatch Alarm State Change
detail:
alarmName: !Ref TargetAlarmNames
state:
value:
- ALARM
Targets:
- Id: DevOpsAlarmWebhookLambdaTarget
Arn: !GetAtt DevOpsAgentWebhookFunction.Arn
Step 3: DevOps Agent Webhook を用意(コンソール / HMAC 署名用)
Webhookの作成 は CloudFormation および CLI 非対応(2026-08-08 時点) — AWS マネジメントコンソールで作成します。
AWS マネジメントコンソールで Agent Space の Webhook を作成します。Webhook は HMAC 認証で利用し、Step 2 の Lambda で署名ヘッダを付与して呼び出します。
- AWS コンソールで AWS DevOps Agent を開き、対象の エージェントスペース を選択
- エージェントスペース の
機能タブを開き、Agent Space ウェブフックセクションで追加を選択 - データスキーマを検証 はそのまま
次へをクリック - ウェブフックの認証タイプ で
HMACを選択し、次へをクリック - ウェブフックを作成してエージェントスペースの調査を開始 で
URL と認証情報を生成するをクリック - 表示された
ウェブフック URLとシークレットキーを控えて自分の URL と認証情報を保存して保管しましたにチェックを入れて追加をクリック
シークレットキー および ウェブフック URL は機密情報として扱い、取得後すぐに Secrets Manager に保存してください。
シークレットキー は画面遷移後に再表示できないため、作成時に必ず安全な場所へ保存してください。
Step 4: Webhook 情報を Secrets Manager に登録(CLI)
Step 2 の CloudFormation で作成した Secrets Manager シークレットに、Step 3 で取得した Webhook 情報を登録します。
DEVOPS_AGENT_WEBHOOK_URLDEVOPS_AGENT_WEBHOOK_SECRET
CloudFormation でシークレット「リソース」は作成し、シークレット値の更新のみ AWS CLI で実施します。
# Step 2 で作成したシークレット名を指定して値を投入
aws secretsmanager put-secret-value \
--secret-id devops-agent-webhook-credentials \
--secret-string '{\"DEVOPS_AGENT_WEBHOOK_URL\":\"https://example.event-ai.ap-northeast-1.amazonaws.com/...\",\"DEVOPS_AGENT_WEBHOOK_SECRET\":\"replace-me\"}' \
--region ap-northeast-1
Step 5: 動作確認
-
DevOps Agent のウェブアプリから
インシデントレスポンスを開き、対象のCloudWatch アラームに対して調査が開始されていることを確認
9. コストとクォータの管理
主要リソースのコスト抑止の整理
機能を豊富に利用するとコストがかさむため、非機能要件に合わせて必要なリソースを適切に利用することでコストを抑止することが重要となります。
| 項目 | 発生アカウント | 削減ポイント |
|---|---|---|
| CloudWatch OAM | 各ソースアカウント | 集約アカウントはソースアカウントのデータをリアルタイムで参照するため、重複コスト無し |
| CloudWatch メトリクス保存 | 各ソースアカウント | 高解像度(1秒)メトリクスを避け標準(60秒)を使用 |
| CloudWatch Logs 保存 | 各ソースアカウント | ロググループの保持期間を明示的に設定(デフォルトは無期限) |
| Route 53 Resolver Inbound Endpoint | 各ソースアカウント | サブネット数を最小限に(AZ 冗長を考慮しつつ) |
| VPC Interface Endpoint | 各アカウント | サブネット数を最小限に(AZ 冗長を考慮しつつ) |
| CloudWatch アラーム | 集約アカウント | 複合アラームでアラーム数を集約して削減 |
| DevOps Agent | 集約アカウント | 自律調査を自動起動させる対象のアラームを選定 |
公式ドキュメント引用: "CloudWatch のクロスアカウントオブザーバビリティでは、ログとメトリクス、Application Signals の追加コストは発生せず"
出典: CloudWatch のクロスアカウントオブザーバビリティ
クォータ制限:設計前に確認すべき上限値
「主に注意すべきアカウント」は、アラーム・通知制御を集約アカウントに集める本記事の運用前提で整理しています。
本構成で使用する主要リソースのクォータを整理します。大量アカウント環境をまとめて管理する場合は、設計前に必ず確認してください。
クォータ値は 2026-08-08 時点で AWS 公式ドキュメントを確認した内容です。
クォータは変更される場合があります。
設計時は必ず AWS Service Quotas コンソール で最新値を確認してください。
OAM(Observability Access Manager)
| クォータ名 | デフォルト値 | 変更可否 | 主に注意すべきアカウント | 注意点 |
|---|---|---|---|---|
| シンク数(アカウントあたり・リージョンごと) | 1 | 不可 | 集約アカウント | 集約アカウントは1リージョンにつきシンクが1つのみです。マルチリージョン構成では各リージョンにシンクを作成します。 |
| シンクあたりのリンク数(ソースアカウント数) | 100,000 | 不可 | 集約アカウント | 地方公共団体向け環境では十分な数量となります。 |
| ソースアカウントあたりのリンク数(監視アカウント数) | 5 | 不可 | ソースアカウント | 1ソースアカウントが接続できる監視アカウントの上限です。複数の監視アカウントを持つ場合でも5つ以内に収める必要があります。 |
参考: CloudWatch Observability Access Manager endpoints and quotas
CloudWatch アラーム
| クォータ名 | デフォルト値 | 変更可否 | 主に注意すべきアカウント | 注意点 |
|---|---|---|---|---|
| PutMetricAlarm API レート | 3 リクエスト/秒 | 可 | 集約アカウント | 大量のアラームを一括作成するスクリプト実行時はスロットリングに注意し、exponential backoff を実装します。 |
| PutCompositeAlarm API レート | 3 リクエスト/秒 | 可 | 集約アカウント | 同様にスロットリングに注意します。 |
Alarm Mute Rules
| クォータ名 | デフォルト値 | 変更可否 | 主に注意すべきアカウント | 注意点 |
|---|---|---|---|---|
| ミュートルール数(アカウントあたり・リージョンごと) | 2,000 | 不可 | 集約アカウント | 集約アカウントでクロスアカウントアラームを大量作成する場合は上限に注意します。 |
| 1ルールあたりの対象アラーム数 | 100 | 不可 | 集約アカウント | 監視対象が100超のアラームをまとめてミュートしたい場合は複数のルールに分割する必要があります。 |
参考: CloudWatch endpoints and quotas
参考: Amazon CloudWatch - AWS SDK for PHP V3
Network Synthetic Monitor
| クォータ名 | デフォルト値 | 変更可否 | 主に注意すべきアカウント | 注意点 |
|---|---|---|---|---|
| モニター数(アカウントあたり・リージョンごと) | 100 | 可 | ソースアカウント | 1 アカウント 1 リージョンに 100 モニターまでです。大量アカウント環境でも各アカウントに 1 モニター作成で問題ありません。 |
| プローブ数(1 モニターあたり) | 24 | 可 | ソースアカウント | 1 モニターで監視できる宛先(ネットワーク機器)の上限です。デバイス数が多い場合は複数モニターに分割します。 |
| プローブ数(1 サブネット・1 モニターあたり) | 4 | 可 | ソースアカウント | 同一サブネットから同一モニター内に作成できるプローブ数の上限です。 |
VPC Interface Endpoint
| クォータ名 | デフォルト値 | 変更可否 | 主に注意すべきアカウント | 注意点 |
|---|---|---|---|---|
| VPCあたりのエンドポイント数 | 50 | 可 | 両方(集約・ソース) | 監視用(monitoring, logs, ssm 等)に加え、他サービスのエンドポイントも同一 VPC に作成する場合は合計数に注意します。集約アカウントでは event-ai など運用系エンドポイントも考慮します。 |
CloudWatch Logs
| クォータ名 | デフォルト値 | 変更可否 | 主に注意すべきアカウント | 注意点 |
|---|---|---|---|---|
| ロググループ数(アカウントあたり) | 1,000,000 | 可 | ソースアカウント | 上限は余裕がありますが、命名規則を統一して管理コストを抑えます。 |
| PutLogEvents スロットリング | 5,000/秒 | 可 | ソースアカウント | 大量送信時はアカウント/リージョンごとの取り込み上限を監視し、必要に応じて Service Quotas で引き上げます。 |
| PutLogEvents バッチサイズ | 1 MB / バッチ | 不可 | ソースアカウント | 大量ログ送信時はバッチサイズに注意します。 |
10. まとめ
AWSサービスで実装する統合監視機能の構成について
課題
SNMP 監視および SNMP Trap 監視が未対応であることや大量アカウント環境で AWS の統合監視を実装する際にミュートルールなどクォータが不足する可能性があるため、現時点では本構成に完全移行することは困難であり、他の統合監視システムと組み合わせて構成する必要があると思います。
| 課題 | 内容 | 根拠(AWS ドキュメント/公開情報) | 主な対策 |
|---|---|---|---|
| SNMP 監視 / SNMP Trap 監視のマネージド未対応 | CloudWatch のマネージド機能だけでは SNMP/SNMP Trap を直接取り込めず、統合監視要件を満たせません。 | AWS Cloud Operations Blog の SNMP 連携例は Logstash 経由であり、CloudWatch ネイティブの直接取り込みではありません。 | SNMP/SNMP Trap は初期段階で別連携方式を検討し、監視対象ごとに責務分界を定義します。 |
| Alarm Mute Rules の上限管理 | 大量アラームを単一ルールで扱えず、メンテナンス時のミュート設計が複雑化します。また、ルール数が不足する可能性があります。 | クォータによりミュートルール数の上限が 2,000、仕様により1 ルール対象アラームが100 | サービス別・機能グループ別にルールを集約します。 |
所感
今年(2026年)に入り、Syslog 監視やアラームのミュート機能が追加されていることから、AWSのマネージドサービスによる統合監視を実現できる日が近づいていると感じ嬉しく思います。
また、DevOps Agentによる自律的な調査で対応時間が実体験として短縮できています。
上記の通り課題はありますが、今後の機能追加を期待し、適宜最新情報を確認して本記事についてもブラッシュアップしていきたいと思います。







