#AWS #Terraform #Lambda #S3 #Glue #Athena #StepFunctions #初心者向け
📁 完全なコードはGitHubで公開:GitHub: pipeiac02
シリーズ一覧(全12回)
Phase 1: 基盤構築
Phase 2: ワークフロー
Phase 3: セキュリティ・運用
Phase 4: 開発効率化
1. はじめに
1-1. 今回のゴール
CloudWatchでパイプラインの監視を設定して、問題を早期発見できるようにします。
| ゴール | 内容 |
|---|---|
| 理解 | CloudWatch監視の仕組みを理解する |
| 実装 | アラームとダッシュボードを作成する |
| 確認 | 監視が機能することを確認する |
1-2. なぜ監視が必要か
前回(第8回)でエラー時の通知を設定しましたが、エラーが起きてからでは遅い 場合もあります。
1-3. この記事で作るもの
2. 比喩で理解する
2-1. CloudWatchを「厨房の監視システム」で考える
レストランでも、問題が起きる前に検知する仕組みがあります。
2-2. 比喩の図解(レストラン)
2-3. 監視システムの役割
| 要素 | 役割 | 例 |
|---|---|---|
| センサー | 状態を計測 | 温度、煙、稼働時間 |
| 警報 | 異常時に通知 | 煙が出たらアラーム |
| 監視パネル | 状況を一覧表示 | 全機器の状態を一目で |
2-4. 対応関係
| レストラン | AWS | 役割 |
|---|---|---|
| センサー | メトリクス | 状態の計測値 |
| 警報 | アラーム | しきい値超えで通知 |
| 監視パネル | ダッシュボード | グラフで可視化 |
| 警報音 | SNS | 通知の送信先 |
2-5. なぜ「兆候」を見るのか
| 兆候 | 放置すると | 監視で検知 |
|---|---|---|
| 処理時間増加 | タイムアウト | ✅ 可能 |
| エラー率上昇 | 大量失敗 | ✅ 可能 |
| メモリ上昇 | OOMエラー | ✅ 可能 |
3. CloudWatchの概要
3-1. 3つの要素
3-2. メトリクス
AWSサービスが自動的に収集する計測値です。
| サービス | メトリクス例 | 意味 |
|---|---|---|
| Lambda | Duration | 実行時間(ミリ秒) |
| Lambda | Errors | エラー回数 |
| Lambda | Invocations | 呼び出し回数 |
| Step Functions | ExecutionsFailed | 失敗回数 |
| Step Functions | ExecutionTime | 実行時間 |
3-3. アラーム
メトリクスがしきい値を超えたら通知します。
| 状態 | 意味 |
|---|---|
| OK | しきい値以下 |
| ALARM | しきい値超過 |
| INSUFFICIENT_DATA | データ不足 |
3-4. ダッシュボード
複数のメトリクスをグラフで一覧表示します。
4. 実装
4-1. ファイル構成
今回作成するファイル:
pipeiac02/
├── test-data/
│ └── monitor-test.json # ★テスト用サンプルデータ
└── tf/
└── cloudwatch.tf # ★今回作成
4-2. アラーム設定(cloudwatch.tf)
# cloudwatch.tf
# ================================
# CloudWatch監視
# ================================
# Lambda用ロググループ
# Lambda関数のログを保存(14日間保持)
resource "aws_cloudwatch_log_group" "lambda_etl" {
name = "/aws/lambda/${aws_lambda_function.etl.function_name}"
retention_in_days = 14
tags = local.common_tags
}
# Lambdaエラーアラーム
# Lambda ETLのエラーを検知してSNS通知
resource "aws_cloudwatch_metric_alarm" "lambda_errors" {
alarm_name = "${var.project}-lambda-errors"
alarm_description = "Lambda ETLのエラーを検知"
comparison_operator = "GreaterThanOrEqualToThreshold"
evaluation_periods = 1
metric_name = "Errors"
namespace = "AWS/Lambda"
period = 300 # 5分
statistic = "Sum"
threshold = 1
# 監視対象のLambda関数を指定
dimensions = {
FunctionName = aws_lambda_function.etl.function_name
}
# アラーム発生時・復旧時にSNS通知
alarm_actions = [aws_sns_topic.alert.arn]
ok_actions = [aws_sns_topic.alert.arn]
tags = local.common_tags
}
4-3. コード解説
| 設定 | 意味 | 料理で例えると |
|---|---|---|
metric_name |
監視する項目 | 温度センサー |
threshold |
しきい値 | 100度を超えたら |
comparison_operator |
比較方法 | より大きい |
period |
計測間隔 | 5分ごとに確認 |
evaluation_periods |
判定回数 | 2回連続で超えたら |
alarm_actions |
通知先 | 警報を鳴らす |
4-4. アラーム設計の考え方
4-5. ダッシュボード設定(cloudwatch.tf に追加)
コード骨格の図解:
コード骨格:
resource "aws_cloudwatch_dashboard" "pipeline" {
dashboard_name = "${var.project}-dashboard"
dashboard_body = jsonencode({
widgets = [
{ type = "metric", x = 0, y = 0, width = 12, height = 6, properties = { title = "Lambda実行時間", metrics = [...] } },
{ type = "metric", x = 12, y = 0, width = 12, height = 6, properties = { title = "Lambdaエラー数", metrics = [...] } },
{ type = "metric", x = 0, y = 6, width = 12, height = 6, properties = { title = "Step Functions成功/失敗", metrics = [...] } },
{ type = "metric", x = 12, y = 6, width = 12, height = 6, properties = { title = "Lambda呼び出し回数", metrics = [...] } }
]
})
}
フルコード:
# cloudwatch.tf に追加
# ================================
# ダッシュボード
# ================================
resource "aws_cloudwatch_dashboard" "pipeline" {
dashboard_name = "${var.project}-dashboard"
dashboard_body = jsonencode({
widgets = [
# Lambda 実行時間
{
type = "metric"
x = 0
y = 0
width = 12
height = 6
properties = {
title = "Lambda 実行時間"
region = "ap-northeast-1"
metrics = [
[
"AWS/Lambda",
"Duration",
"FunctionName",
aws_lambda_function.etl.function_name,
{ stat = "Average", period = 300 }
]
]
}
},
# Lambda エラー数
{
type = "metric"
x = 12
y = 0
width = 12
height = 6
properties = {
title = "Lambda エラー数"
region = "ap-northeast-1"
metrics = [
[
"AWS/Lambda",
"Errors",
"FunctionName",
aws_lambda_function.etl.function_name,
{ stat = "Sum", period = 300 }
]
]
}
},
# Step Functions 実行結果
{
type = "metric"
x = 0
y = 6
width = 12
height = 6
properties = {
title = "Step Functions 成功/失敗"
region = "ap-northeast-1"
metrics = [
[
"AWS/States",
"ExecutionsSucceeded",
"StateMachineArn",
aws_sfn_state_machine.pipeline.arn,
{ stat = "Sum", period = 300, color = "#2ca02c" }
],
[
"AWS/States",
"ExecutionsFailed",
"StateMachineArn",
aws_sfn_state_machine.pipeline.arn,
{ stat = "Sum", period = 300, color = "#d62728" }
]
]
}
},
# Lambda 呼び出し回数
{
type = "metric"
x = 12
y = 6
width = 12
height = 6
properties = {
title = "Lambda 呼び出し回数"
region = "ap-northeast-1"
metrics = [
[
"AWS/Lambda",
"Invocations",
"FunctionName",
aws_lambda_function.etl.function_name,
{ stat = "Sum", period = 300 }
]
]
}
}
]
})
}
ポイント解説:
| 設定 | 意味 | 例 |
|---|---|---|
dashboard_name |
ダッシュボード名 | dp-dashboard |
dashboard_body |
ウィジェット定義(JSON) | widgets配列 |
type |
ウィジェット種別 |
metric(グラフ) |
x, y
|
配置位置(グリッド座標) | (0,0)が左上 |
width, height
|
サイズ(グリッド単位) | 12x6 |
metrics |
表示するメトリクス | ["AWS/Lambda", "Duration", ...] |
stat |
集計方法 |
Sum, Average
|
period |
集計間隔(秒) | 300(5分) |
color |
グラフの色 |
#2ca02c(緑) |
4-6. ダッシュボードレイアウト
| 位置 | ウィジェット | 座標 (x, y) | サイズ |
|---|---|---|---|
| 左上 | Lambda 実行時間 | (0, 0) | 12x6 |
| 右上 | Lambda エラー数 | (12, 0) | 12x6 |
| 左下 | Step Functions 成功/失敗 | (0, 6) | 12x6 |
| 右下 | Lambda 呼び出し回数 | (12, 6) | 12x6 |
5. 動作確認
5-1. 計画(プレビュー)
cd pipeiac02/tf
terraform plan
期待される出力:
Plan: 4 to add, 0 to change, 0 to destroy.
5-2. 適用(作成)
terraform apply
5-3. アラームの確認
aws cloudwatch describe-alarms --alarm-name-prefix dp- --query 'MetricAlarms[].{Name:AlarmName,State:StateValue}'
期待される出力:
[
{
"Name": "dp-lambda-errors",
"State": "OK"
},
{
"Name": "dp-lambda-duration",
"State": "OK"
},
{
"Name": "dp-sfn-failed",
"State": "OK"
}
]
5-4. ダッシュボードの確認
AWSコンソールで確認:
- CloudWatch → ダッシュボード
-
dp-dashboardを選択 - 4つのグラフが表示されることを確認
5-5. テストデータで動作確認
リポジトリに含まれている test-data/monitor-test.json を使用します。
# 正常データをアップロード
aws s3 cp test-data/monitor-test.json s3://dp-raw-$(terraform output -raw bucket_suffix)/input/
# 5分後にダッシュボードを確認
5-6. アラームテスト(オプション)
意図的にエラーを発生させてアラームを確認します。リポジトリに含まれている test-data/invalid-json.json を使用します。
# 不正データでエラーを発生させる
aws s3 cp test-data/invalid-json.json s3://dp-raw-$(terraform output -raw bucket_suffix)/input/bad.json
# アラーム状態を確認
sleep 60
aws cloudwatch describe-alarms --alarm-name-prefix dp- --query 'MetricAlarms[].{Name:AlarmName,State:StateValue}'
5-7. 確認チェックリスト
| 確認項目 | 期待値 |
|---|---|
| アラーム作成 | 3つ作成されている |
| アラーム状態 | OK(正常時) |
| ダッシュボード | 4つのグラフが表示 |
| SNS連携 | アラーム時に通知 |
6. まとめ
6-1. この記事でやったこと
| 項目 | 内容 |
|---|---|
| 理解 | CloudWatch監視の仕組みを学んだ |
| 実装 | アラーム3つ + ダッシュボード |
| 確認 | 監視が機能することを確認 |
6-2. 比喩の振り返り
| レストラン | AWS | 今回やったこと |
|---|---|---|
| センサー | メトリクス | 自動収集(AWS提供) |
| 警報 | アラーム | 3つ設定 |
| 監視パネル | ダッシュボード | 4グラフ作成 |
6-3. 監視設計の全体像
6-4. 作成したアラーム一覧
| アラーム | 条件 | 用途 |
|---|---|---|
| lambda-errors | Errors > 0 | エラー検知 |
| lambda-duration | Duration > 30秒 | 遅延検知 |
| sfn-failed | ExecutionsFailed > 0 | パイプライン失敗検知 |
6-5. 次回予告
第10回: Terraform設計 では、コードの整理を行います。
- ファイル構成の見直し
- モジュール化の検討
- 変数・出力の整理
レストランで言うと「レシピ本の整理」をしていきます。