Skip to content

kohei3110/sql-database-backup-alert

Repository files navigation

Azure SQL Database backup alert

Azure Container Apps Job で sys.dm_database_backups の最新履歴を定期確認し、想定期間内にバックアップ履歴がない場合に Slack Incoming Webhook へ通知する監視ツールです。コンテナは Node.js 24 系で動作する前提です。

Azure SQL Database の自動バックアップは、成功したバックアップ履歴として DMV に現れます。このツールは「最新の Full / Differential / Transaction log バックアップが設定した猶予時間内に存在するか」で失敗や遅延を検知します。DMV のクエリ自体が失敗した場合もアラート扱いです。

監視条件

既定値は Azure SQL Database の標準バックアップ頻度に余裕を持たせています。

種別 DMV 値 既定の許容期間
Full D 8 日
Differential I 30 時間
Transaction log L 60 分

BACKUP_CHECK_WINDOWS で変更できます。

BACKUP_CHECK_WINDOWS=D=11520,I=1800,L=60

コード構成

src/backupMonitor.js は CLI entry point と互換 export だけを持ち、実装は責務ごとに分割しています。

ファイル 責務
config.js 環境変数の読み込みと検証
backupHistoryQuery.js / sqlBackupHistoryRepository.js DMV クエリ生成と SQL Server 接続
backupHistoryEvaluator.js / simulatedBackupHistory.js 監視結果の判定と疑似アラート生成
slackNotifier.js / consoleReporter.js Slack payload 生成、送信、コンソール出力
backupMonitorService.js / cli.js ユースケースの orchestration と CLI 引数処理

必要な権限

監視ユーザーは対象データベースで sys.dm_database_backups を参照できる必要があります。多くのサービスレベルでは VIEW DATABASE STATE で足ります。

CREATE USER backup_monitor WITH PASSWORD = '<strong-password>';
GRANT VIEW DATABASE STATE TO backup_monitor;

Basic / S0 / S1、または Elastic Pool では、サーバー管理者、Microsoft Entra ID 管理者、または ##MS_ServerStateReader## サーバーロールが必要です。

Hyperscale はスナップショット方式のため、この DMV は結果を返しません。Hyperscale ではこの DMV ベースの監視は使用しないでください。

ローカル実行

Node.js 24 以上を使います。

npm install
cp .env.example .env

.env を編集してから環境変数として読み込んで実行します。

set -a
. ./.env
set +a

npm run check

JSON で確認する場合:

npm run check:json

Slack 送信なしで動作確認する場合:

node src/backupMonitor.js --dry-run --json

疑似アラート

Slack Incoming Webhook や Azure SQL Database に接続できない検証環境では、SIMULATE_ALERT=trueSLACK_PRINT_PAYLOAD=true を使うと、DB へ接続せずに意図的なアラート状態を生成し、Slack に送る payload をコンソールへ表示できます。

set -a
. ./.env.simulated.example
set +a

npm run check

このモードでは終了コードは 1 になり、スケジューラーや GitHub Actions 上でも失敗アラート相当の挙動を確認できます。実際の Slack 送信は SLACK_WEBHOOK_URL を設定した場合だけ行われます。

SIMULATE_ALERT=true の場合は SQL 接続情報が未設定でも simulated-server.database.windows.net / simulated-database として動作します。

Azure Container Apps Job で定期実行

Container Apps Job の Schedule trigger で 15 分ごとに単発実行します。Cron は UTC で評価されます。

まず ACR にイメージをビルドします。

export RESOURCE_GROUP=rg-sql-backup-alert
export LOCATION=japaneast
export ACR_NAME=<globally-unique-acr-name>
export ACA_ENVIRONMENT=cae-sql-backup-alert
export JOB_NAME=sql-backup-alert
export IMAGE_NAME=sql-database-backup-alert
export IMAGE_TAG=$(date +%Y%m%d%H%M%S)
export ACR_LOGIN_SERVER="$ACR_NAME.azurecr.io"
export IMAGE="$ACR_LOGIN_SERVER/$IMAGE_NAME:$IMAGE_TAG"

az group create \
  --name "$RESOURCE_GROUP" \
  --location "$LOCATION"

az acr create \
  --resource-group "$RESOURCE_GROUP" \
  --name "$ACR_NAME" \
  --sku Basic

az acr build \
  --registry "$ACR_NAME" \
  --image "$IMAGE_NAME:$IMAGE_TAG" \
  .

az containerapp env create \
  --name "$ACA_ENVIRONMENT" \
  --resource-group "$RESOURCE_GROUP" \
  --location "$LOCATION"

Slack / SQL Database なしで疑似アラートだけ確認する Job:

az containerapp job create \
  --name "$JOB_NAME" \
  --resource-group "$RESOURCE_GROUP" \
  --environment "$ACA_ENVIRONMENT" \
  --trigger-type Schedule \
  --cron-expression "*/15 * * * *" \
  --replica-timeout 300 \
  --replica-retry-limit 0 \
  --parallelism 1 \
  --replica-completion-count 1 \
  --image "$IMAGE" \
  --cpu 0.25 \
  --memory 0.5Gi \
  --mi-system-assigned \
  --registry-server "$ACR_LOGIN_SERVER" \
  --registry-identity system \
  --env-vars \
    SIMULATE_ALERT=true \
    SLACK_PRINT_PAYLOAD=true \
    SLACK_MENTION="<!here>" \
    BACKUP_CHECK_WINDOWS=D=11520,I=1800,L=60

実際に Azure SQL Database と Slack に接続する Job:

export SQL_SERVER=your-server.database.windows.net
export SQL_DATABASE=your-database
export SQL_USERNAME=backup_monitor
export SQL_PASSWORD='<password>'
export SLACK_WEBHOOK_URL='https://hooks.slack.com/services/...'

az containerapp job create \
  --name "$JOB_NAME" \
  --resource-group "$RESOURCE_GROUP" \
  --environment "$ACA_ENVIRONMENT" \
  --trigger-type Schedule \
  --cron-expression "*/15 * * * *" \
  --replica-timeout 300 \
  --replica-retry-limit 0 \
  --parallelism 1 \
  --replica-completion-count 1 \
  --image "$IMAGE" \
  --cpu 0.25 \
  --memory 0.5Gi \
  --mi-system-assigned \
  --registry-server "$ACR_LOGIN_SERVER" \
  --registry-identity system \
  --secrets \
    sql-password="$SQL_PASSWORD" \
    slack-webhook-url="$SLACK_WEBHOOK_URL" \
  --env-vars \
    SQL_SERVER="$SQL_SERVER" \
    SQL_DATABASE="$SQL_DATABASE" \
    SQL_AUTH_MODE=sql \
    SQL_USERNAME="$SQL_USERNAME" \
    SQL_PASSWORD=secretref:sql-password \
    SLACK_WEBHOOK_URL=secretref:slack-webhook-url \
    BACKUP_CHECK_WINDOWS=D=11520,I=1800,L=60 \
    SLACK_NOTIFY_ON_SUCCESS=false

手動で即時実行する場合:

az containerapp job start \
  --name "$JOB_NAME" \
  --resource-group "$RESOURCE_GROUP"

疑似アラートまたはバックアップ異常時はコンテナの終了コードが 1 になるため、Container Apps Job の実行結果は失敗として記録されます。アラートがない場合は 0、設定不備は 2 です。

GitHub Actions で検証

.github/workflows/backup-alert.yml は Node.js 24 でテストを実行します。手動実行時に simulate_alert=true を指定すると、DB に接続せず疑似アラートを発生させ、Slack payload を Actions log に表示します。定期実行は GitHub Actions ではなく Azure Container Apps Job が担当します。

任意の Repository variables:

Variable 用途
BACKUP_CHECK_WINDOWS 例: D=11520,I=1800,L=60
SLACK_MENTION 例: <!here>

コンテナ実行

docker build --build-arg NODE_VERSION=24 -t sql-database-backup-alert .
docker run --rm --env-file .env sql-database-backup-alert

終了コードは正常時 0、バックアップ履歴異常またはクエリ失敗時 1、設定エラー時 2 です。

About

SQL Databaseバックアップアラートサンプル

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages