この記事について
この記事は、生成AIを活用した自動生成フローで作成しています。旧記事の内部style_promptと重複H1を除去し、jq/yqの役割、HTTP失敗検知、変換前検証、秘密情報、設定ファイル置換の注意点を見直しました。検証ステータス:✅ jq/yqの標準的な変換パターンを再確認
CI/CDで外部APIのJSONからYAML設定を生成する場合、重要なのは「変換できた」ことより、不正な入力を本番設定へ反映しないことです。取得、検証、変換、差分確認、反映を分離するとトラブルを切り分けやすくなります。
安全な処理順序
- HTTP取得が成功したことを確認する。
- JSONとして解析でき、必須フィールドがあるか検証する。
- 必要な部分だけをYAMLへ変換する。
- 生成物を構文チェックし、必要なら差分を確認する。
- 本番ファイルと同一ファイルシステム上の一時ファイルから置換する。
最小スクリプト例
#!/usr/bin/env bash
set -euo pipefail
: "${SOURCE_URL:?SOURCE_URL is required}"
DEST="/etc/app/config.yaml"
DEST_DIR="$(dirname "$DEST")"
TMP_JSON="$(mktemp)"
TMP_YAML="$(mktemp "${DEST_DIR}/.config.yaml.XXXXXX")"
trap 'rm -f "$TMP_JSON" "$TMP_YAML"' EXIT
curl --fail-with-body --silent --show-error --location \
--retry 3 "$SOURCE_URL" -o "$TMP_JSON"
jq -e '
(.metadata.name | type == "string") and
(.spec | type == "object")
' "$TMP_JSON" >/dev/null
# mikefarah/yq v4を想定
yq -p=json -o=yaml '.spec' "$TMP_JSON" > "$TMP_YAML"
yq '.' "$TMP_YAML" >/dev/null
chmod 0644 "$TMP_YAML"
chown root:root "$TMP_YAML"
mv -f "$TMP_YAML" "$DEST"
mvによる置換を原子的に扱いたい場合、一時ファイルと宛先を同じファイルシステム上に置くことが重要です。別ファイルシステム間では単純なrenameにならない場合があります。
「必須フィールドがある」だけでは足りない
jq -e '.metadata.name'だけでは、値が文字列か、specが期待する構造かまで確認できません。可能ならJSON Schemaや対象アプリケーション自身のdry-run/validation機能も利用します。
秘密情報をログへ出さない
APIトークンを環境変数やシークレットストアから渡す場合、set -xやエラー出力にAuthorizationヘッダーを出さないよう注意します。生成したYAML自体に秘密値が含まれる場合は、ファイル権限や保存先も別途設計します。
yqは実装を明記する
yqには複数の実装があります。本記事の例はmikefarah/yq v4系を前提にしています。CIイメージではバージョンを固定し、ローカルとCIで構文差が出ないようにします。
参考情報
この記事の更新履歴
- 2026-09-14 追加:HTTP失敗検知、型検証、同一ファイルシステム上での一時ファイル作成、yq実装明記を追加。
- 2026-09-14 変更:単純なJSON→YAML変換例から、検証と安全な反映を分離したCI/CD手順へ変更。
- 2026-09-14 削除:内部style_prompt、本文H1、未検証ドラフト表記、
sudo installを原子的置換と断定する説明を削除。

