1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

account_idチェックが壊れたまま「OK」を返すバグの再現と修正|シングルクォートと[env]セクション

1
Last updated at Posted at 2026-10-14

この記事で扱うこと

wrangler deploy の前に account_id を確かめる小さな Bash スクリプトで、本来止めるべき設定を通してしまう不具合が2つ見つかりました。再現手順、原因、修正前後の差分だけをまとめます。

再現手順

適当な作業ディレクトリで、修正前スクリプト(check-account.sh)に次の2ファイルを渡します。

$ printf "account_id = '0123456789abcdef0123456789abcdef'\n" > single.toml
$ ./check-account.sh single.toml
OK: account_id=account_id = '0123456789abcdef0123456789abcdef'

$ printf '[env.prod]\naccount_id = "prod222"\n' > envonly.toml
$ ./check-account.sh envonly.toml
OK: account_id=prod222

どちらも終了コード 0 です。1つ目は値の中に行全体が入っており、2つ目はトップレベルに account_id が無いのに通っています。

原因

  1. sed は一致しないと入力をそのまま出す。 抽出用の正規表現が "..." しか想定しておらず、TOML で正しい書き方の '...'(リテラル文字列)では置換が起きません。後段は「空かどうか」しか見ないので通過します。
  2. grep がファイル全体を検索している。 [env.prod] などセクション内の行も拾うため、トップレベルの指定の有無を判定できていません。
  3. さらに根本的には、取り出した値が実在する自分のアカウントかを確かめていませんでした。抽出ミスも打ち間違いも、ここで止められたはずです。

修正前後の差分

@@ -1,18 +1,22 @@
 #!/usr/bin/env bash
-# デプロイ前のフェイルセーフ: 設定ファイルに account_id があり、
-# CLOUDFLARE_ACCOUNT_ID が設定されている場合は一致していることを確認する。
-# 使い方: ./check-account.sh [wrangler.toml|wrangler.jsonc]
+# デプロイ前のフェイルセーフ(v2): 設定ファイルの account_id が、
+# いまログインしている Wrangler のアカウント一覧(wrangler whoami)に含まれるか確認する。
+# 使い方: ./check-account-v2.sh [wrangler.toml|wrangler.jsonc]
 set -euo pipefail
 cfg="${1:-wrangler.toml}"
+WRANGLER="${WRANGLER:-npx wrangler}"   # テスト時はモックに差し替え可能
 [ -f "$cfg" ] || { echo "NG: $cfg が見つかりません" >&2; exit 1; }
-id="$(grep -E '^[[:space:]]*"?account_id"?[[:space:]]*[=:]' "$cfg" | head -n1 \
-      | sed -E 's/.*[=:][[:space:]]*"([^"]+)".*/\1/' || true)"
-if [ -z "$id" ]; then
-  echo "NG: $cfg に account_id がありません(誤アカウントへのデプロイを防ぐため必須)" >&2
-  exit 1
-fi
+scope="$(awk '/^[[:space:]]*\[/{exit} {print}' "$cfg")"   # 最初の [section] より前だけ
+case "$cfg" in *.json|*.jsonc) scope="$(cat "$cfg")";; esac
+id="$(printf '%s\n' "$scope" \
+      | grep -E '^[[:space:]]*"?account_id"?[[:space:]]*[=:]' | head -n1 \
+      | sed -nE "s/.*[=:][[:space:]]*[\"']([^\"']+)[\"'].*/\1/p" || true)"
+[ -n "$id" ] || { echo "NG: $cfg のトップレベルから account_id を読み取れません" >&2; exit 1; }
 if [ -n "${CLOUDFLARE_ACCOUNT_ID:-}" ] && [ "$CLOUDFLARE_ACCOUNT_ID" != "$id" ]; then
-  echo "NG: CLOUDFLARE_ACCOUNT_ID と $cfg の account_id が一致しません" >&2
-  exit 1
+  echo "NG: CLOUDFLARE_ACCOUNT_ID と $cfg の account_id が一致しません" >&2; exit 1
+fi
+who="$($WRANGLER whoami 2>&1)" || { echo "NG: wrangler whoami が失敗しました(未ログイン?)" >&2; exit 1; }
+if ! printf '%s\n' "$who" | grep -qwF -- "$id"; then
+  echo "NG: account_id=$id はログイン中の認証情報で操作できるアカウントにありません" >&2; exit 1
 fi
-echo "OK: account_id=$id"
+echo "OK: account_id=$id(wrangler whoami で確認)"

変更点:

  • awk で最初の [section] より前だけを対象にした(jsonc は従来どおり全体)。
  • sed を -n ... /p にし、一致しなかったら空になるようにした。クォートは " と ' の両方を許可。
  • wrangler whoami の出力に、その account_id が単語として含まれるかを確認。ログイン中の認証情報で扱えないアカウントなら止まる。未ログインで whoami が失敗した場合も止まる。

動作確認

ログインなしでも再現できるよう、wrangler whoami をアカウント表を返すモック(WRANGLER=./mock-wrangler)に差し替えて9ケースを検証しています。CIに組み込む前に、実際の認証情報で一度動作を確かめてください。

== ok.toml / single.toml / c.jsonc / commented.toml
OK: account_id=0123456789abcdef0123456789abcdef(wrangler whoami で確認)
== envonly.toml
NG: envonly.toml のトップレベルから account_id を読み取れません
== none.toml
NG: none.toml のトップレベルから account_id を読み取れません
== other.toml   # account_id = 'aaa111'(whoami の一覧に無い)
NG: account_id=aaa111 はログイン中の認証情報で操作できるアカウントにありません
== 未ログイン(モックが exit 1)
NG: wrangler whoami が失敗しました(未ログイン?)

残っている制限

  • jsonc で env 内の account_id がトップレベルより前にあると、そちらを読みます。厳密に扱うならコメントを除去して jq '.account_id' で読む方法があります。
  • whoami の出力形式は Wrangler のバージョンで変わる可能性があります。ここでは表の中にIDが単語として含まれるかだけを見ています。

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?