こんにちは、インフラエンジニアの綿引です。 今回は AWS CloudFormation で EC2・ALB・RDS (Aurora) の CloudWatch ダッシュボードを作成したいと思います。 CloudWatch ダッシュボードでモニタリングを行いたが、「監視したいメトリクスが多い」や「環境毎に設定するのが面倒」という理由で敬遠されている方も多いのではないでしょうか? 私も上記の理由でなかなか手を出せずにいたのですが、今回 CloudFormation を用いることでこれを解決できましたので、宜しければ参考にして頂ければと思います。 対象の方は以下のような方でしょうか。 EC2・ALB・RDS (Aurora)を CloudWatch ダッシュボード でモニタリングしたい CloudWatch ダッシュボードを手動で作りたくない 監視の内製化を検討している テンプレートファイル作成 では早速テンプレートファイルを作成していきます。 改めてモニタリング対象のサービスは以下です。 EC2 ALB RDS (Aurora) 以下にソースを記載しますが、もし「EC2 だけでいい」や「ALB と RDS (Aurora) だけでいい」などあれば不要部分を削って頂ければと思います。 監視項目とメトリクス一覧 今回監視するメトリクスを一覧にしました。 監視項目(自分で勝手につけました)と対応するメトリクス、名前空間を記載しています。 どのサービスの監視項目かは名前空間を見て頂ければと思います。 監視項目 名前空間 監視メトリクス EC2 CPU 使用率 AWS/EC2 CPUUtilization EC2 CPU クレジットバランス AWS/EC2 CPUCreditBalance EC2 メモリ使用率 CWAgent mem_used_percent EC2 swap 使用率 CWAgent swap_used_percent EC2 ディスク読み取り回数 CWAgent diskio_reads EC2 ディスク書き込み回数 CWAgent diskio_writes EC2 ディスクI/O 時間 CWAgent diskio_io_time EC2 ディスク使用率 CWAgent disk_used_percent EC2 ステータスチェック失敗 AWS/EC2 StatusCheckFailed “ “ StatusCheckFailed_Instance “ “ StatusCheckFailed_System ALB 正常ターゲット数 AWS/ApplicationELB HealthyHostCount ALB リクエスト数 AWS/ApplicationELB RequestCount ALB ターゲットの応答時間 (秒) AWS/ApplicationELB TargetResponseTime ALB 有効接続数 AWS/ApplicationELB ActiveConnectionCount ALB 新規接続数 AWS/ApplicationELB NewConnectionCount ALB プロセスされたバイト数 AWS/ApplicationELB ProcessedBytes ALB 接続エラー数 (ALB 最大接続超過) AWS/ApplicationELB RejectedConnectionCount ALB 接続エラー数 (LB – ターゲット間) AWS/ApplicationELB TargetConnectionErrorCount ALB TLS接続エラー数 (クライアント – LB間) AWS/ApplicationELB ClientTLSNegotiationErrorCount ALB TLS接続エラー数 (LB – ターゲット間) AWS/ApplicationELB TargetTLSNegotiationErrorCount ALB ELB 3XX (カウント) AWS/ApplicationELB HTTPCode_ELB_3XX_Count ALB ELB 4XX (カウント) AWS/ApplicationELB HTTPCode_ELB_4XX_Count ALB ELB 5XX (カウント) AWS/ApplicationELB HTTPCode_ELB_5XX_Count Aurora CPU 使用率 AWS/RDS CPUUtilization Aurora DatabaseConnections AWS/RDS DatabaseConnections Aurora 空きメモリ容量 AWS/RDS FreeableMemory Aurora CPU クレジットバランス AWS/RDS CPUCreditBalance Aurora クエリ実行回数 (秒) AWS/RDS Queries Aurora デットロック回数 (秒) AWS/RDS Deadlocks Aurora Select レイテンシー AWS/RDS SelectLatency Aurora Insert レイテンシー AWS/RDS InsertLatency Aurora Update レイテンシー AWS/RDS UpdateLatency Aurora Commit レイテンシー AWS/RDS CommitLatency Aurora Delete レイテンシー AWS/RDS DeleteLatency 構成や環境などによって監視したいメトリクスも異なるかとは思いますので、必要なメトリクスがなかったり、不要なメトリクスがある場合は、任意でカスタマイズして頂ければと思います。 また「EC2 ステータスチェック失敗」のみ、インスタンスステータスチェックと、システムステータスチェックのどちらで失敗しているかを把握したかったため、複数の監視メトリクスを指定しています。 テンプレートファイル 次は実際のテンプレートファイルです。 今回も yaml で記載しています。 基本的に可変部分は「Parameters」を用いることで共有化しているため、Parameters 部分を環境に合わせて変更いただければ問題ないと思います。 また念のため、CloudFormation 側が成功しても、ダッシュボード側で問題なくメトリクスが表示されているかを確認いただけると間違いないかと思います。 変更点・注意点を以下に記載しますのでご確認ください。 環境に合わせて「Parameters」の XXXX 部分を変更 「EC2 ディスク」関連項目の name,device の「nvme0n1」と、fstype の「xfs」は必要に応じて変更 CloudFormation 成功後にダッシュボード側をちゃんと確認 AWSTemplateFormatVersion: '2010-09-09' Description: CloudWatch Dashboard ##################################################################### # Parameters 設定 ##################################################################### Parameters: Ec2InstanceId: Description: Ec2 InstanceId Type: AWS::EC2::Instance::Id Ec2ImageId: Description: Ec2 ImageId (AMIID) Type: String Default: ami-XXXXXXXXXXXX # EC2 の ImageId を記載 Ec2InstanceType: Description: Ec2 InstanceType Type: String Default: XXXXXX # インスタンスタイプを記載 AlbLoadBalancer: Description: AlbLoadBalancer Type: String Default: app/XXXXXX/XXXXXXXXXXX # ALB の ARN を記載 AlbTargetGroup: Description: ALB TargetGroup Type: String Default: targetgroup/XXXXXX/XXXXXXXXXXX # ターゲットグループの ARN を記載 RdsDBInstanceIdentifier: Description: RDS DBInstanceIdentifier Type: String Default: XXXXXX # DB クラスター識別子を記載 ##################################################################### # Resources 設定 ##################################################################### Resources: # CloudWatchダッシュボードの定義 ##################################################################### # ダッシュボード設定 ##################################################################### CWDashboard: Type: AWS::CloudWatch::Dashboard Properties: DashboardName: !Sub '${AWS::StackName}' DashboardBody: !Sub | { "widgets": [ { "type": "metric", "x": 0, "y": 0, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/EC2", "CPUUtilization", "InstanceId", "${Ec2InstanceId}" ] ], "region": "ap-northeast-1", "yAxis": { "left": { "min": 0, "max": 100 } }, "title": "EC2 CPU 使用率" } }, { "type": "metric", "x": 12, "y": 0, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/EC2", "CPUCreditBalance", "InstanceId", "${Ec2InstanceId}" ] ], "region": "ap-northeast-1", "title": "EC2 CPU クレジットバランス" } }, { "type": "metric", "x": 0, "y": 6, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "CWAgent", "mem_used_percent", "InstanceId", "${Ec2InstanceId}", "ImageId", "${Ec2ImageId}", "InstanceType", "${Ec2InstanceType}" ] ], "region": "ap-northeast-1", "yAxis": { "left": { "min": 0, "max": 100 } }, "title": "EC2 メモリ使用率" } }, { "type": "metric", "x": 12, "y": 6, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "CWAgent", "swap_used_percent", "InstanceId", "${Ec2InstanceId}", "ImageId", "${Ec2ImageId}", "InstanceType", "${Ec2InstanceType}" ] ], "region": "ap-northeast-1", "title": "EC2 swap 使用率" } }, { "type": "metric", "x": 0, "y": 12, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "CWAgent", "diskio_reads", "InstanceId", "${Ec2InstanceId}", "ImageId", "${Ec2ImageId}", "name", "nvme0n1", "InstanceType", "${Ec2InstanceType}" ] ], "region": "ap-northeast-1", "title": "EC2 ディスク読み取り回数" } }, { "type": "metric", "x": 12, "y": 12, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "CWAgent", "diskio_writes", "InstanceId", "${Ec2InstanceId}", "ImageId", "${Ec2ImageId}", "name", "nvme0n1", "InstanceType", "${Ec2InstanceType}" ] ], "region": "ap-northeast-1", "title": "EC2 ディスク書き込み回数" } }, { "type": "metric", "x": 12, "y": 18, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "CWAgent", "diskio_io_time", "InstanceId", "${Ec2InstanceId}", "ImageId", "${Ec2ImageId}", "name", "nvme0n1", "InstanceType", "${Ec2InstanceType}" ] ], "region": "ap-northeast-1", "title": "EC2 ディスクI/O 時間" } }, { "type": "metric", "x": 0, "y": 18, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "CWAgent", "disk_used_percent", "path", "/", "InstanceId", "${Ec2InstanceId}", "ImageId", "${Ec2ImageId}", "InstanceType", "${Ec2InstanceType}", "device", "nvme0n1p1", "fstype", "xfs" ] ], "region": "ap-northeast-1", "yAxis": { "left": { "label": "", "max": 100, "min": 0 } }, "title": "EC2 ディスク使用率" } }, { "type": "metric", "x": 0, "y": 24, "width": 24, "height": 6, "properties": { "view": "timeSeries", "stacked": true, "metrics": [ [ "AWS/EC2", "StatusCheckFailed", "InstanceId", "${Ec2InstanceId}" ], [ ".", "StatusCheckFailed_Instance", ".", "." ], [ ".", "StatusCheckFailed_System", ".", "." ] ], "region": "ap-northeast-1", "title": "EC2 ステータスチェック失敗" } }, { "type": "metric", "x": 0, "y": 30, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/ApplicationELB", "HealthyHostCount", "TargetGroup", "${AlbTargetGroup}", "LoadBalancer", "${AlbLoadBalancer}", "AvailabilityZone", "ap-northeast-1a" ] ], "region": "ap-northeast-1", "title": "ALB 正常ターゲット数" } }, { "type": "metric", "x": 12, "y": 30, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/ApplicationELB", "RequestCount", "TargetGroup", "${AlbTargetGroup}", "LoadBalancer", "${AlbLoadBalancer}", "AvailabilityZone", "ap-northeast-1a" ] ], "region": "ap-northeast-1", "title": "ALB リクエスト数" } }, { "type": "metric", "x": 0, "y": 42, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/ApplicationELB", "TargetResponseTime", "LoadBalancer", "${AlbLoadBalancer}", "AvailabilityZone", "ap-northeast-1a" ] ], "region": "ap-northeast-1", "title": "ALB ターゲットの応答時間 (秒)" } }, { "type": "metric", "x": 0, "y": 36, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/ApplicationELB", "ActiveConnectionCount", "LoadBalancer", "${AlbLoadBalancer}" ] ], "region": "ap-northeast-1", "title": "ALB 有効接続数" } }, { "type": "metric", "x": 12, "y": 36, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/ApplicationELB", "NewConnectionCount", "LoadBalancer", "${AlbLoadBalancer}" ] ], "region": "ap-northeast-1", "title": "ALB 新規接続数" } }, { "type": "metric", "x": 12, "y": 42, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/ApplicationELB", "ProcessedBytes", "LoadBalancer", "${AlbLoadBalancer}" ] ], "region": "ap-northeast-1", "title": "ALB プロセスされたバイト数" } }, { "type": "metric", "x": 0, "y": 48, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/ApplicationELB", "RejectedConnectionCount", "LoadBalancer", "${AlbLoadBalancer}" ] ], "region": "ap-northeast-1", "title": "ALB 接続エラー数 (ALB 最大接続超過)" } }, { "type": "metric", "x": 12, "y": 48, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/ApplicationELB", "TargetConnectionErrorCount", "LoadBalancer", "${AlbLoadBalancer}" ] ], "region": "ap-northeast-1", "title": "ALB 接続エラー数 (LB - ターゲット間)" } }, { "type": "metric", "x": 12, "y": 54, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/ApplicationELB", "ClientTLSNegotiationErrorCount", "LoadBalancer", "${AlbLoadBalancer}" ] ], "region": "ap-northeast-1", "title": "ALB TLS接続エラー数 (クライアント - LB間)" } }, { "type": "metric", "x": 0, "y": 54, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/ApplicationELB", "TargetTLSNegotiationErrorCount", "LoadBalancer", "${AlbLoadBalancer}" ] ], "region": "ap-northeast-1", "title": "ALB TLS接続エラー数 (LB - ターゲット間)" } }, { "type": "metric", "x": 0, "y": 60, "width": 6, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/ApplicationELB", "HTTPCode_ELB_3XX_Count", "LoadBalancer", "${AlbLoadBalancer}" ] ], "region": "ap-northeast-1", "title": "ALB ELB 3XX (カウント)" } }, { "type": "metric", "x": 6, "y": 60, "width": 6, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/ApplicationELB", "HTTPCode_ELB_4XX_Count", "LoadBalancer", "${AlbLoadBalancer}" ] ], "region": "ap-northeast-1", "title": "ALB ELB 4XX (カウント)" } }, { "type": "metric", "x": 12, "y": 60, "width": 6, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/ApplicationELB", "HTTPCode_ELB_5XX_Count", "LoadBalancer", "${AlbLoadBalancer}" ] ], "region": "ap-northeast-1", "title": "ALB ELB 5XX (カウント)" } }, { "type": "metric", "x": 0, "y": 66, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/RDS", "CPUUtilization", "DBClusterIdentifier", "${RdsDBInstanceIdentifier}" ] ], "region": "ap-northeast-1", "title": "Aurora CPU 使用率" } }, { "type": "metric", "x": 0, "y": 72, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/RDS", "DatabaseConnections", "DBClusterIdentifier", "${RdsDBInstanceIdentifier}" ] ], "region": "ap-northeast-1", "title": "Aurora DatabaseConnections" } }, { "type": "metric", "x": 12, "y": 72, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/RDS", "FreeableMemory", "DBClusterIdentifier", "${RdsDBInstanceIdentifier}" ] ], "region": "ap-northeast-1", "title": "Aurora 空きメモリ容量" } }, { "type": "metric", "x": 12, "y": 66, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/RDS", "CPUCreditBalance", "DBClusterIdentifier", "${RdsDBInstanceIdentifier}" ] ], "region": "ap-northeast-1", "title": "Aurora CPU クレジットバランス" } }, { "type": "metric", "x": 0, "y": 78, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/RDS", "Queries", "DBClusterIdentifier", "${RdsDBInstanceIdentifier}" ] ], "region": "ap-northeast-1", "title": "Aurora クエリ実行回数 (秒)" } }, { "type": "metric", "x": 12, "y": 78, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/RDS", "Deadlocks", "DBClusterIdentifier", "${RdsDBInstanceIdentifier}" ] ], "region": "ap-northeast-1", "title": "Aurora デットロック回数 (秒)" } }, { "type": "metric", "x": 0, "y": 84, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/RDS", "SelectLatency", "DBClusterIdentifier", "${RdsDBInstanceIdentifier}" ] ], "region": "ap-northeast-1", "title": "Aurora Select レイテンシー" } }, { "type": "metric", "x": 12, "y": 84, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/RDS", "InsertLatency", "DBClusterIdentifier", "${RdsDBInstanceIdentifier}" ] ], "region": "ap-northeast-1", "title": "Aurora Insert レイテンシー" } }, { "type": "metric", "x": 12, "y": 90, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/RDS", "UpdateLatency", "DBClusterIdentifier", "${RdsDBInstanceIdentifier}" ] ], "region": "ap-northeast-1", "title": "Aurora Update レイテンシー" } }, { "type": "metric", "x": 0, "y": 90, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/RDS", "CommitLatency", "DBClusterIdentifier", "${RdsDBInstanceIdentifier}" ] ], "region": "ap-northeast-1", "title": "Aurora Commit レイテンシー" } }, { "type": "metric", "x": 0, "y": 96, "width": 12, "height": 6, "properties": { "view": "timeSeries", "stacked": false, "metrics": [ [ "AWS/RDS", "DeleteLatency", "DBClusterIdentifier", "${RdsDBInstanceIdentifier}" ] ], "region": "ap-northeast-1", "title": "Aurora Delete レイテンシー" } } ] } 実際のソース ソースは以下 GitHub に上げておきましたので宜しければお使いください。 GitHub : CloudFormation-Templates CloudWatch-Dashboard ※ 随時更新しているため上記記載の内容とは若干異なる場合があります 最後に 今回は CloudFormation を使って CloudWatch のダッシュボードを作成しました。 ソースはちょっと長いですが、CloudWatch ダッシュボードは個別に用意することがしんどいので CloudFormation でできると非常に嬉しいです。 今回は「プロセス監視」の部分はダッシュボードに含めませんでしたが、今後加えようかなと思っております。 次は CloudWatch Alarm を作ってみようと思います。