JSON/YAML相互変換によるマルチクラウド設定ファイルの自動生成と配布の自動化

Tech

{ “style_prompt”: “tech_sre_standard”, “priority”: “robustness_and_portability”, “tools”: [“jq”, “yq”, “curl”, “systemd”], “language”: “ja-JP” } 本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。

JSON/YAML相互変換によるマルチクラウド設定ファイルの自動生成と配布の自動化

【導入と前提】 APIから取得したJSONデータを基に、冪等性を保ちつつYAML設定ファイルを生成・検証・デプロイする一連のオペレーションを自動化・堅牢化します。

  • 前提 OS: Ubuntu 22.04 LTS / RHEL 9 (Linux全般)

  • 必須ツール: jq (JSONプロセッサ), yq (YAMLプロセッサ v4+), curl

【処理フローと設計】

graph TD
A["外部API / JSONデータ"] -->|curl| B("テンポラリ保存")
B -->|jq: フィルタリング| C{"スキーマ検証"}
C -->|yq: 変換| D["YAML設定ファイル生成"]
D -->|diff: 差分比較| E{"変更あり?"}
E -->|Yes| F["設定適用 / 再起動"]
E -->|No| G["終了"]

JSON形式で提供される動的なインベントリ情報や環境変数を、ミドルウェア(PrometheusやKubernetes等)が読み取り可能なYAML形式へ安全に変換・適用するフローを構築します。

【実装:堅牢な自動化スクリプト】

#!/bin/bash


# ==============================================================================


# Script: sync_config.sh


# Description: JSON APIからYAML設定を生成し、サービスをリロードする


# ==============================================================================

set -euo pipefail # エラー発生で停止、未定義変数参照禁止、パイプラインエラーの捕捉
IFS=$'\n\t'

# --- 設定 ---

API_URL="https://api.example.com/v1/config"
WORK_DIR="/tmp/config_sync"
OUTPUT_YAML="/etc/myapp/config.yaml"
BACKUP_YAML="${OUTPUT_YAML}.bak"
SERVICE_NAME="myapp.service"

# 一時ディレクトリの作成と終了時の自動クリーンアップ

trap 'rm -rf "$WORK_DIR"' EXIT
mkdir -p "$WORK_DIR"

echo "[INFO] 設定の同期を開始します..."

# 1. APIからJSONを取得 (curl)


# -s: 進捗非表示, -S: エラー表示, -L: リダイレクト追従, -f: HTTPエラーで失敗


# --retry: 通信失敗時のリトライ回数

if ! curl -sSLf --retry 3 "$API_URL" -o "$WORK_DIR/src.json"; then
    echo "[ERROR] APIからのデータ取得に失敗しました。" >&2
    exit 1
fi

# 2. jqによる検証と整形


# データが空でないか、特定のフィールドが存在するかを確認

if [[ $(jq '.items | length' "$WORK_DIR/src.json") -eq 0 ]]; then
    echo "[WARN] 取得したデータが空です。処理を中断します。"
    exit 0
fi

# 3. yqによるJSONからYAMLへの変換


# -P: Pretty print (YAML出力)

yq eval -P "$WORK_DIR/src.json" > "$WORK_DIR/new_config.yaml"

# 4. 差分確認と適用(冪等性の確保)

if [ -f "$OUTPUT_YAML" ] && diff -q "$OUTPUT_YAML" "$WORK_DIR/new_config.yaml" > /dev/null; then
    echo "[INFO] 変更はありません。終了します。"
else
    echo "[INFO] 変更を検知しました。設定を更新します。"
    [ -f "$OUTPUT_YAML" ] && cp "$OUTPUT_YAML" "$BACKUP_YAML" # バックアップ作成

    # アトミックなファイル置換

    install -m 644 "$WORK_DIR/new_config.yaml" "$OUTPUT_YAML"

    # 5. サービスのバリデーションとリロード


    # systemd環境を想定

    if systemctl is-active --quiet "$SERVICE_NAME"; then
        echo "[INFO] サービスをリロードします: $SERVICE_NAME"
        systemctl reload "$SERVICE_NAME" || systemctl restart "$SERVICE_NAME"
    fi
fi

echo "[SUCCESS] 全ての工程が完了しました。"

systemd タイマー設定例

定期的な実行を自動化するため、/etc/systemd/system/config-sync.timer を作成します。

[Unit]
Description=Run configuration sync every 15 minutes

[Timer]
OnCalendar=*:0/15
RandomizedDelaySec=30
Persistent=true

[Install]
WantedBy=timers.target

【検証と運用】

  1. 正常系の確認コマンド: sudo systemctl start config-sync.service で手動実行し、ls -l /etc/myapp/config.yaml でファイルが生成されているか確認します。

  2. ログ確認: 実行結果は journalctl -u config-sync.service で確認可能です。標準出力・標準エラー出力が全て記録されます。

  3. YAML構文チェック: 変換後のファイルが正しいか yq eval '.' /etc/myapp/config.yaml で検証します。

【トラブルシューティングと落とし穴】

  • 権限問題: /etc/ 以下の書き換えには sudo が必要です。スクリプトを root ユーザーの crontab または systemd ユニットとして実行してください。

  • yq のバージョン: yq は v3 と v4 で文法が大きく異なります。本スクリプトは v4 (mikefarah版) を想定しています。

  • 環境変数の秘匿: APIキーなどを含む場合は、スクリプト内にハードコードせず export API_KEY=$(vault read ...) 等の手段で環境変数から読み込むようにしてください。

  • 部分的な書き換え: ファイル全体を置換せず、特定のキーのみ更新したい場合は yq eval '.key = "value"' -i file.yaml を使用します。

【まとめ】 運用の冪等性を維持するための3つのポイント:

  1. 差分比較 (diff): 内容に変更がない場合はプロセスを再起動しない。

  2. アトミックな更新: install コマンドや mv を使い、不完全な状態のファイルが読み込まれるのを防ぐ。

  3. エラーハンドリング: set -etrap を組み合わせ、異常終了時にゴミ(一時ファイル)を残さない。

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。

コメント

タイトルとURLをコピーしました