{
"status": "work_in_progress",
"component": "SRE_Automation_Toolkit",
"tools": ["curl", "jq", "bash", "systemd"],
"reliability_level": "Draft_Unverified",
"security_focus": ["Error_Handling", "Sensitive_Data_Protection"]
}
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
APIヘルスチェックの堅牢化:curlとjqによる自動検証とsystemd統合
【導入と前提】
REST APIの応答整合性を自動検証し、異常検知時に安全に停止・通知するSRE向けスクリプトの構築手法。
- 前提条件: Linux OS,
curl(7.70.0+),jq(1.6+) がインストールされていること。
【処理フローと設計】
graph TD
A["Start: Timer/Cron"] --> B["curl: API Request"]
B --> C{"HTTP Status 200?"}
C -- No --> D["Error Log & Exit"]
C -- Yes --> E["jq: Parse JSON Body"]
E --> F{"Validate Business Logic"}
F -- Invalid --> G["Alert: JSON Schema/Value Error"]
F -- Valid --> H["End: Success Update"]
リクエストフェーズ:
curlのリトライ機能を使い、一時的なネットワークエラーを許容。パースフェーズ:
jqの終了コード (-e) を利用して、期待するフィールドの存在を確認。終了フェーズ:
set -euo pipefailにより、パイプラインの途中で発生したエラーを確実に捕捉。
【実装:堅牢な自動化スクリプト】
1. API検証スクリプト (api_check.sh)
#!/bin/bash
# ==============================================================================
# API Response Validator
# Description: REST APIのレスポンスを検証し、異常があれば非ゼロで終了する。
# ==============================================================================
set -euo pipefail
# -e: エラー発生時に即座に終了
# -u: 未定義変数参照時にエラー
# -o pipefail: パイプライン途中のエラーも検知
readonly API_URL="https://api.example.com/v1/health"
readonly EXPECTED_VERSION="1.2.0"
readonly TMP_FILE=$(mktemp /tmp/api_response.XXXXXX.json)
# 終了時に一時ファイルを確実に削除
trap 'rm -f "$TMP_FILE"' EXIT
echo "[INFO] Starting API check for $API_URL"
# 1. APIリクエスト実行
# -s: 進捗表示を非表示 (Silent)
# -S: エラー時はメッセージを表示 (Show error)
# -L: リダイレクトに追従 (Location)
# --retry: 通信失敗時のリトライ回数
# -w: HTTPステータスコードを抽出
HTTP_STATUS=$(curl -sSL --retry 3 \
-o "$TMP_FILE" \
-w "%{http_code}" \
"$API_URL")
# 2. HTTPステータスコードの検証
if [[ "$HTTP_STATUS" != "200" ]]; then
echo "[ERROR] HTTP Status $HTTP_STATUS received." >&2
exit 1
fi
# 3. jqによるJSON整合性の検証
# -e: 条件に合致しない(nullやfalse)場合に終了コード 1 を返す
# -r: 出力からクォートを除去 (Raw output)
echo "[INFO] Validating JSON response..."
if ! jq -e ".status == \"ok\" and .version == \"$EXPECTED_VERSION\"" "$TMP_FILE" > /dev/null; then
echo "[ERROR] JSON validation failed. Unexpected status or version." >&2
cat "$TMP_FILE" >&2
exit 1
fi
echo "[SUCCESS] API health check passed."
2. systemd タイマーによる定期実行 (api-check.timer)
# /etc/systemd/system/api-check.service [Unit] Description=API Health Check Service [Service] Type=oneshot ExecStart=/usr/local/bin/api_check.sh User=nobody Group=nogroup # /etc/systemd/system/api-check.timer [Unit] Description=Run API Health Check every 5 minutes [Timer] OnCalendar=*:0/5 Persistent=true [Install] WantedBy=timers.target
【検証と運用】
正常系の確認
スクリプトを直接実行し、終了コードが 0 であることを確認します。
./api_check.sh echo $? # 0が表示されればOK
異常系のログ確認 (systemd)
APIがダウン、または期待しないJSONを返した場合は、journalctl で詳細を確認します。
# 失敗した直近のログを表示 journalctl -u api-check.service -n 50 --no-pager
【トラブルシューティングと落とし穴】
パイプラインの罠:
curl | jqと記述すると、curlが失敗(404など)してもjq自体が正常に動作すれば、パイプ全体の終了コードが0になるリスクがあります。必ずset -o pipefailを使うか、-oオプションで一時ファイルに書き出してから検証してください。機密情報の露出:
curl -vをデバッグで使う際、Authorizationヘッダーがログに残らないよう注意してください。本番環境では-sSを推奨します。一時ファイルの肥大化:
mktempで作成したファイルはtrapで確実に消去します。OSの再起動まで残る/tmpを圧迫しない設計が重要です。
【まとめ】
運用の冪等性と堅牢性を維持するための3つのポイント:
Fail-fastの徹底:
set -euo pipefailをシェルスクリプトの「一丁目一番地」とする。型と値の両面検証: HTTPコードだけでなく、
jqを使ってビジネスロジック(期待するステータス値やバージョン)まで踏み込んで検証する。副作用の最小化:
trapによるクリーンアップと、systemdユーザー権限(nobody推奨)による最小権限実行を組み合わせる。

