NGINX map & geo Conditional Routing Prompt
Replace a brittle pile of nested if blocks with clean map and geo directives — for feature flags, country routing, or per-host variables — so your config is fast, readable, and free of the 'if is evil' traps.
- Target user
- Engineers building conditional logic into NGINX config without rewrites or if blocks
- Difficulty
- Intermediate
- Tools
- Claude, ChatGPT, Cursor
The prompt
You are a senior infrastructure engineer who refuses to write logic with `if` inside `location` blocks because you know the "if is evil" failure modes. You reach for `map` and `geo` to compute variables once, cleanly, at request time. I will provide: - The decision I'm trying to make: [DESCRIBE — e.g. route by country, flag internal IPs, pick a backend by Host or header] - The input variable: [DESCRIBE — $http_x_..., $remote_addr, $host, $request_uri] - The possible outcomes and their default: [LIST CASES + DEFAULT] - Where the result gets used: [proxy_pass target, header value, access control, etc.] Build the config: 1. **Choose map vs geo** — use `geo` when the key is a client IP/CIDR (it's CIDR-aware), `map` for everything else (headers, hostnames, URIs). State which you picked and why. 2. **The block** — write the `map`/`geo` at the `http` level producing a single variable. Include a sensible `default`, use `hostnames;` for host matching where appropriate, and quote values that need it. For regex cases, show the `~` prefix and note case-insensitive `~*`. 3. **Consumption** — show exactly where the computed variable is referenced (a `proxy_pass`, an `add_header`, a `return`, an `allow/deny` via a separate mechanism), and warn about anything `map` can't safely drive. 4. **The if you avoided** — briefly show the nested-`if` version this replaces and explain the specific bug it would have caused (e.g. directives silently ignored inside `if`). Output: (a) the complete `map`/`geo` block plus its consumption site, commented, (b) a one-line note on evaluation order (maps evaluate lazily, on first use), (c) a curl test that exercises two different inputs and the `nginx -t` line. Validate with `nginx -t` and reload — do not edit live config in place.
Why this prompt works
NGINX’s configuration language tempts everyone into writing imperative if blocks, and the official docs literally have a page titled “If is Evil” because if inside a location silently drops many directives and produces config that looks right and behaves wrong. The idiomatic answer is to compute a variable once with map (for headers, hosts, URIs) or geo (for CIDR-aware IP matching) and then consume that variable. This prompt makes the map-vs-geo decision explicit and demands a justification, which is exactly the choice people get wrong — using a plain map on $remote_addr and losing CIDR matching.
Forcing the model to show the if-based version it’s replacing, and to name the specific bug that version would cause, turns the refactor into a teaching artifact. You don’t just get cleaner config; you understand why the cleaner config is also more correct.
The consumption-site requirement keeps the abstraction honest. A map is only useful if its variable is referenced somewhere valid, and there are places (like driving access control alone) where a computed variable is necessary but not sufficient. Surfacing that boundary, plus a two-input curl test, means you ship logic you’ve actually exercised rather than a clever block you assume works.
Related prompts
-
NGINX location & Regex Precedence Prompt
Figure out exactly which location block NGINX picks for a given request and fix the ordering bug that's routing your URL to the wrong handler — with the matching rules made explicit, not folklore.
-
NGINX Rate & Connection Limiting Prompt
Design limit_req and limit_conn zones that throttle abusive traffic and protect your backend — with burst, nodelay, and per-route tuning — without rate-limiting your own legitimate users into 503s.