Azure Front Door Standard/Premium で URL リライトを設定しようとして、「/8003/(.*) がマッチしない」「$1 や {request.path[2]} が展開されない」「クエリ文字列が付け替えられない」といった壁にぶつかるケースはとても多いです。この記事では https://id.sample.com/8003/12121212 を https://id.sample.com/?view=sample&id=12121212 に変換したい、という具体例を軸に、Azure Front Door の URL リライト仕様と、正しい書式・設計パターンを詳しく解説します。
Azure Front Door の URL リライトで何がしたいのか
まず、今回のゴールを整理します。
元URL : https://id.sample.com/8003/12121212
目標 : https://id.sample.com/?view=sample&id=12121212
やりたいことをもう少し分解すると、次の 3 つです。
- パス先頭の
/8003/で始まる URL を対象にしたい - パスの残りの部分
12121212を「ID」として取り出したい - 取り出した ID をクエリ文字列
?view=sample&id=12121212として組み立てたい
多くの人が最初に思いつくのは、次のような正規表現風の書き方です。
- ソースパターン:
/8003/(.*) - 宛先パターン:
/?view=sample&id=$1や/?view=sample&id={request.path[2]}
しかし、Azure Front Door Standard/Premium の URL リライトでは、このような書き方は動きません。理由は、仕様レベルで次の制約があるからです。
URL リライトの仕様を理解する(ソース/宛先パターン)
ソースパターンは「プレフィックス一致」のみ
Azure Front Door Standard/Premium の URL rewrite アクションにおける「Source pattern」は、正規表現ではなく「プレフィックス一致」だけをサポートしています。
- OK:
/8003/のような固定プレフィックス - OK:
/(すべてのパスにマッチ) - NG:
/8003/*、/8003/(.*)のようなワイルドカード - NG:
^/8003/(.*)$といった正規表現構文
さらに重要なのが、「ソースパターンとして評価されるのは、ルートの Patterns to match で指定したパスより後ろだけ」という点です。
| 設定箇所 | 例 | ルールセット側から見えるパス |
|---|---|---|
| Route: Patterns to match | /* | /8003/12121212 全体 |
| Route: Patterns to match | /id/* | リクエスト /id/8003/12121212 の場合、/8003/12121212 が Source pattern の対象 |
つまり、「ルートでどこまでを前提とするか」を先に決め、その後ろ側に対して /8003/ のような固定プレフィックスでマッチさせる、という二段構えの設計になります。
宛先(Destination)は「パスだけ」書き換えられる
URL rewrite アクションの「Destination」は、名前のとおりパス部分だけを扱います。公式ドキュメントの説明や UI を見ても、宛先として指定できるのは /foo/ のようなパスのみで、?view=... といったクエリ文字列を含める構造にはなっていません。
また、Microsoft Q&A でも「パスの先頭が ? のような特殊文字の場合、Front Door レベルでは想定どおり動作しない(サポート外)」と明言されています。
そのため、
Destination = /?view=sample&id=12121212のような指定は非サポート- クエリ文字列を付け替えたい場合は、URL rewrite ではなく URL redirect アクション側で「Query string」を設定する
という設計にする必要があります。URL redirect であれば、ホスト・パス・クエリ文字列をまとめて変更できることが公式に案内されています。
サーバー変数 {url_path:seg#} でパスの一部を取り出す
では「パスの一部(12121212)だけを ID として取り出して、クエリに流し込みたい」場合はどうするべきでしょうか。
Azure Front Door では、そのためにサーバー変数が用意されています。特に URL パス向けには、次のような変数が使えます。
{url_path:seg0}: 最初のパスセグメント{url_path:seg1}: 2 番目のパスセグメント{url_path:seg2}: 3 番目のパスセグメント{url_path:seg1:3}:seg1から 3 セグメント分(1〜3){url_path:seg2:2147483647}:seg2以降を末尾まで全部
例えば、次のような URL を考えます。
https://id.sample.com/8003/12121212
ルートの「Patterns to match」が /* の場合、パス部分は次のように分割されます。
| パス | セグメント | サーバー変数 |
|---|---|---|
/8003/12121212 | seg0 = 8003 | {url_path:seg0} |
seg1 = 12121212 | {url_path:seg1} |
したがって、ID 部分だけを取り出したければ {url_path:seg1} を使えば良いことがわかります。
注意点として、ルート側で /id/* のようにプレフィックスを切り出している場合、そのプレフィックスもセグメントに含まれるため、番号が 1 つずれることがあります。実際の値は、ログ出力や一時的なレスポンスヘッダーの書き換えなどで確認しておくと安全です。
実現パターン別の具体的な設定例
ここからは、要件別に代表的な 3 パターンを紹介します。
- A:クエリ付きの URL へ リダイレクトしたい
- B:内部的にパスだけ 書き換えたい(クエリ不要)
- C:ルート設定だけでプレフィックスを落としたい
A. クエリ付き URL にリダイレクトする(もっとも素直な解)
クライアント側に 30x 応答を返してよいのであれば、URL redirect アクションを使うのが一番シンプルです。
やりたいことはこうです。
https://id.sample.com/8003/12121212
↓ HTTP 302/301 などでリダイレクト
https://id.sample.com/?view=sample&id=12121212
このときの設定例を表にまとめます。
| 項目 | 設定値(例) | 補足 |
|---|---|---|
| ルールの一致条件 | Request path ・Begins with ・8003/ | 先頭の / はあってもなくても同義 |
| アクション種別 | URL Redirect | リライトではなくリダイレクトを選択 |
| Destination path | / | 最終的に /(トップ)へ飛ばす |
| Query string | view=sample&id={url_path:seg1} | パス 2 番目のセグメントを ID として利用 |
| Redirect type | 302 / 307 / 301 / 308 から要件に応じて選択 | 恒久なら 301/308、一時的なら 302/307 など |
これで、パス /8003/12121212 の「12121212」だけを抽出し、クエリ文字列として組み立てた上でトップページにリダイレクトできます。
なお、Query string には静的文字列とサーバー変数を混在させて書けるため、例えば次のような複雑な書き方も可能です。
view=sample&id={url_path:seg1}&src=frontdoor&raw={url_path:seg0:2}
このように、クエリ文字列の操作をしたい場合は、「URL rewrite ではなく URL redirect アクションを使う」と覚えておくと混乱が減ります。
B. 内部転送だけでよい場合(パスのリライトのみ)
もし要件が「クエリはいらないので、/8003/ の付いた URL を内部的に別パスへ転送したい」だけであれば、URL rewrite アクションだけで完結します。
例えば、次のようにしたいとします。
https://id.sample.com/8003/12121212 → https://id.sample.com/12121212 (内部転送)
設定例は次のとおりです。
| 項目 | 設定値(例) | 説明 |
|---|---|---|
| アクション種別 | URL Rewrite | 内部転送のためリライトを選ぶ |
| Source pattern | /8003/ | ここはプレフィックス一致のみ |
| Destination | / | 元の /8003/ を / に置き換えるイメージ |
| Preserve unmatched path | Yes | /8003/ 以降の部分(12121212)を後ろにくっつける |
この設定では、リクエスト時の URL は変わらず、バックエンドへのフォワード時だけパスが /12121212 に変わるため、クライアント側のブックマークや SEO に影響を与えずに内部構成を整理できます。
同じ考え方で、
/v1/api/*→/api/*に統合する/old/*→/new/*に読み替えてバックエンドへ流す
といった用途にも応用できます。
C. ルートの Origin path だけでプレフィックスを落とす
場合によっては、そもそもルールセットを使わずに「ルート設定だけで完結させる」方がシンプルなケースもあります。
例えば、次のような要件です。
- 外部公開 URL:
https://id.sample.com/8003/... - バックエンドアプリの実 URL:
https://backend/...(/8003 は不要)
この場合、ルートを次のように設定すると、追加のルールなしでプレフィックスを落とせます。
| 項目 | 設定例 |
|---|---|
| Patterns to match | /8003/* |
| Origin path | / |
これにより、/8003/12121212 で来たリクエストは、そのまま /12121212 としてバックエンドに転送されます。単にプレフィックスを落としたいだけなら、この方法が最小構成で済みます。
書式(文法)のチートシート:ソース/宛先パターンとサーバー変数
ソースパターンの書式と注意点
ソースパターンの仕様はシンプルですが、正規表現に慣れている人ほどハマりがちです。よくある例を表にまとめます。
| 書き方 | 意味 | 動作 |
|---|---|---|
/ | すべてのパスにマッチ | ○ |
/8003/ | /8003/ で始まるパスにマッチ | ○ |
/8003/* | 正規表現っぽいが… | ×(ワイルドカードはサポート外) |
/8003/(.*) | (.*) でキャプチャしたい | ×(正規表現は使えない) |
^/8003/(.*)$ | フル正規表現 | × |
「URL のどこまでをルートでマッチさせるか」「その後ろで何を Source pattern にするか」をきちんと切り分けて考えるのがコツです。
Destination(宛先パス)の書式
Destination は、ソースパターンにマッチした部分を何に置き換えるか、というパスを指定します。クエリ文字列は含められない点に注意してください。
| 書き方 | 意味 | 例 |
|---|---|---|
/ | ソースパターンを / に置き換える | /8003/12121212 → /12121212 |
/bar/ | /foo/ を /bar/ に変換 | /foo/1.jpg → /bar/1.jpg |
/?view=sample | クエリを含めたい例 | ×(サポート外) |
一方、URL redirect アクションであれば、Destination path と Query string を別々に指定できるため、パスは /、クエリは view=sample&id=... のように柔軟に組み立てられます。
サーバー変数 {url_path:seg#} の実用レシピ
サーバー変数を使うと、パスの特定位置だけを抽出・再構成できます。ここでは、実際に役立つ書き方を例でまとめます。
| 用途 | 例 | 書き方 |
|---|---|---|
| 2 番目のセグメントを ID として使う | /8003/12121212 → ID = 12121212 | {url_path:seg1} |
| 先頭を固定プレフィックス、それ以降をまとめて使う | /app/v1/orders/123 → v1/orders/123 | {url_path:seg1:2147483647} |
| 一部を差し替えて新しいパスにする | /seg0/seg1/seg2/seg3 → /seg0/insert/seg2/seg3 | /{url_path:seg0}/insert/{url_path:seg2:2147483647} |
最後の例のように、サーバー変数と静的な文字列をつなぎ合わせることで、「一部だけ入れ替え・その他はそのまま」という高度な転送ロジックも組み立てられます。
よくあるつまずきポイントと Q&A からの学び
$1 や {request.path[2]} が効かない
Azure CDN や他製品の経験があると、思わず次のような書き方をしてしまいがちです。
- ソースパターン:
/8003/(.*) - 宛先:
/?view=sample&id=$1
しかし、Azure Front Door の URL リライトは、そもそもソースパターンで正規表現のキャプチャをサポートしていません。また、{request.path[2]} のような書式も Front Door 独自のフォーマットとは異なるため無効です。かわりに、サーバー変数 {url_path:seg#} を使って、同等のロジックを組み立てる必要があります。
「?」で始まる宛先パスが動かない
Microsoft Q&A では、「宛先パスを ?view=sample&id=... にしても動作しない」という質問に対して、「パスが ? で始まるケースは Front Door レベルでは想定外/サポート外」との回答が掲載されています。
この点は仕様上の制約であり、URL rewrite でクエリ文字列を生成しようとするアプローチ自体が誤りです。クエリを操作したい場合は、必ず URL redirect アクションの「Query string」欄にサーバー変数を含めて設定しましょう。
CDN 時代の「(.*) を全部持ってくる」書き換えができない
従来の Azure CDN では、(.*) をフルキャプチャして別の URL に埋め込むような設定が可能でした。それに対し、Front Door Standard/Premium では、{url_path:seg#} を組み合わせて似た動作を再現する必要があります。
例えば、「/content/* を /media/pdf/*?<SAS token> に書き換えたい」ようなケースでは、
- パス部分は URL rewrite で
/content/→/media/pdf/ - 末尾のパス部分を
{url_path:seg1:2147483647}で保持 - SAS トークン付きのクエリは URL redirect で設定
といったように、「パスの書き換え」「クエリの付与」を分けて考えると整理しやすくなります。
動作確認とトラブルシュートのポイント
どのルールがヒットしているかを確かめる
Front Door のアクセスログには、どの Ruleset / Rule がヒットしたかを表す項目が含まれています。この情報を見れば、「そもそもルールまで届いていない」のか「ルールは当たっているが書き換え内容がおかしい」のかを切り分けることができます。
特に、Route の Patterns to match が想定とズレていると、ルールセット側の Source pattern に到達する前にマッチ条件から外れてしまうことがあるため、ログと併せて確認すると安心です。
curl やブラウザの開発者ツールで 30x を確認する
URL redirect を使う場合は、実際にどのステータスコード・Location ヘッダーが返っているかを確認すると、設定ミスを早期に発見できます。
curl -I "https://id.sample.com/8003/12121212"
HTTP/1.1 302 Found
Location: https://id.sample.com/?view=sample&id=12121212
このように期待どおりの Location が返っていれば、クエリの組み立ては正しく動いています。もし {url_path:seg#} の指定を間違えていれば、Location にそのまま文字列が入るので(例:id={url_path:seg1} のまま)、すぐに検知できます。
アプリ側での Request.Path / Query の状態も確認する
バックエンドのアプリケーション側では、実際にどのようなパス・クエリでリクエストが届いているかをログに出しておくと、Front Door 側の設定と突き合わせる際に非常に役立ちます。
- .NET なら
HttpContext.Request.Path,HttpContext.Request.QueryString - Node.js (Express) なら
req.path,req.query
Front Door の設定を変えたら、アプリ側のログも合わせて確認する、という運用フローを作っておくと、想定外の動作をすぐに検知できます。
要件別:どの機能を使うべきか早見表
最後に、「何をしたいときにどの機能を使うべきか」を一覧で整理します。
| やりたいこと | 推奨機能 | ポイント |
|---|---|---|
| パスのプレフィックスだけ落として内部転送したい | URL Rewrite または Route の Origin path | クエリ操作不要ならリライトで十分 |
| パスの一部を使ってクエリ文字列を生成したい | URL Redirect(Rule set) | {url_path:seg#} を Query string に埋め込む |
| HTTP→HTTPS への統一や別ドメインへの誘導 | URL Redirect | プロトコル・ホスト・パス・クエリをまとめて制御可能 |
| アプリにはそのまま見せたいが、キャッシュキー用にパスを変えたい | URL Rewrite + キャッシュ設定 | 内部転送なのでクライアント URL は変わらない |
| CDN 時代の正規表現ベースのルールを移行したい | URL Rewrite/Redirect + サーバー変数 | 正規表現は使えないので、セグメント分割に置き換える |
まとめ:Azure Front Door の URL リライトを正しく使うために
ここまでのポイントを整理すると、次のようになります。
- ソースパターンは「プレフィックス一致のみ」であり、正規表現や
$1といったキャプチャは使えない。 - URL rewrite の Destination は「パス」専用であり、
/?view=...のようにクエリを含む書き方はサポート外。 - クエリ文字列を組み立てたい場合は、URL redirect アクションで Query string を指定し、
{url_path:seg#}などのサーバー変数を組み合わせる。 - プレフィックスを落とすだけなら、ルートの Origin path 設定で完結させる方法もある。
特に、今回のような
/8003/{ID} → /?view=sample&id={ID}
という要件では、
- ルールセットの一致条件で
Request path begins with 8003/ - URL redirect アクションで
Destination path = / Query string = view=sample&id={url_path:seg1}
という構成にすることで、Front Door の仕様に沿った形でシンプルに実現できます。
「正規表現でキャプチャして $1 をクエリに埋め込む」という発想から、「パスをセグメント単位で分けて、サーバー変数として組み立て直す」という発想に切り替えると、Azure Front Door Standard/Premium の URL リライト・リダイレクト設計が一気にわかりやすくなるはずです。

コメント