Skip to content

Commit 3c3a25b

Browse files
Add NVA Routing sample: route APIM outbound traffic through Azure Firewall in a hub/spoke topology (#181)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: simonkurtz-MSFT <84809797+simonkurtz-MSFT@users.noreply.github.com> Co-authored-by: Simon Kurtz <simonkurtz@microsoft.com>
1 parent db0b891 commit 3c3a25b

13 files changed

Lines changed: 1033 additions & 78 deletions

.github/copilot-instructions.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ Uniformity, clarity, and ease of use are paramount across all infrastructures an
5454
- **Keep README structure uniform.** Infrastructure READMEs and sample READMEs each follow their own standard layout (see the guidelines below). Readers should be able to predict where to find objectives, configuration steps, and execution instructions.
5555
- **Reuse shared utilities.** Use `NotebookHelper`, `InfrastructureNotebookHelper`, `ApimRequests`, `ApimTesting`, and shared Bicep modules rather than inventing ad-hoc alternatives. Shared code is the single best tool for enforcing uniformity.
5656
- **Mirror tone and depth.** Similar sections across artefacts should use similar levels of detail. If one sample's README explains configuration in three sentences, another sample of comparable complexity should do the same.
57+
- **Sort samples alphabetically.** Wherever samples are listed (README tables, landing page cards, JSON-LD structured data, diagrams, AGENTS.md), they must appear in alphabetical order by their display name. Infrastructures keep their current deliberate ordering.
58+
- **Use consistent sample display names.** The display name used for a sample in README tables, landing page cards, JSON-LD, and compatibility diagrams must be identical. The canonical name is the one shown in the compatibility-matrix SVG diagram (e.g. "Costing", not "Costing & Showback"; "OAuth 3rd-Party", not "Credential Manager (with Spotify)"). Longer descriptions belong in the Description column or card body text, not in the name.
5759
- **Validate against peers.** Before finalising a new infrastructure or sample, compare it side-by-side with at least one existing peer to identify structural or stylistic drift.
5860

5961
## General Coding Guidelines
@@ -423,6 +425,8 @@ Check `docs/README.md` for local preview instructions and styling notes. The pag
423425
- The Draw.io diagrams were created with the [Azure Draw.io MCP Server](https://github.com/simonkurtz-MSFT/drawio-mcp-server).
424426
- Keep diagrams simple. For Azure, include major components, not individual aspects of components. For example, there is no need for individual policies in WAFs or APIs in API Management, Smart Detector Alert Rules, etc.
425427
- Less is more. Don't be too verbose in the diagrams.
428+
- Sample names in compatibility-matrix diagrams are the canonical display names. README tables, landing page cards, and JSON-LD entries must use the same names. When adding or renaming a sample, update the diagram and all listings together.
429+
- Samples in compatibility-matrix diagrams must be listed in alphabetical order by display name.
426430
- Never include subscription IDs, resource group names, or any other sensitive information in the diagrams. That data is not relevant.
427431

428432
### KQL (Kusto Query Language) Instructions

AGENTS.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ This repository provides resources to deploy Azure API Management infrastructure
2727
│ ├── authX-pro/ # Advanced auth with policy fragments
2828
│ ├── azure-maps/ # Azure Maps integration
2929
│ ├── costing/ # APIM costing and showback
30+
│ ├── egress-control/ # Egress control via NVA routing
3031
│ ├── general/ # Basic policy demonstrations
3132
│ ├── load-balancing/ # Backend pool load balancing
32-
│ ├── oauth-3rd-party/ # Credential Manager (Spotify example)
33+
│ ├── oauth-3rd-party/ # OAuth 3rd-party (Spotify example)
3334
│ └── secure-blob-access/ # Valet key pattern for blob storage
3435
3536
├── shared/ # Reusable components

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,11 @@ It's quick and easy to get started!
6767
| [AuthX][sample-authx] | Authentication and role-based authorization in a mock HR API. | All infrastructures |
6868
| [AuthX Pro][sample-authx-pro] | Authentication and role-based authorization in a mock product with multiple APIs and policy fragments. | All infrastructures |
6969
| [Azure Maps][sample-azure-maps] | Proxying calls to Azure Maps with APIM policies. | All infrastructures |
70-
| [Costing & Showback][sample-costing] | Track and allocate API costs per business unit using APIM subscriptions, Log Analytics, and Cost Management. | All infrastructures |
71-
| [Credential Manager (with Spotify)][sample-oauth-3rd-party] | Authenticate with APIM which then uses its Credential Manager with Spotify's REST API. | All infrastructures |
70+
| [Costing][sample-costing] | Track and allocate API costs per business unit using APIM subscriptions, Log Analytics, and Cost Management. | All infrastructures |
71+
| [Egress Control][sample-egress-control] | Control APIM outbound internet traffic by routing it through a Network Virtual Appliance (NVA) in a hub/spoke topology. | appgw-apim, appgw-apim-pe |
7272
| [General][sample-general] | Basic demo of APIM sample setup and policy usage. | All infrastructures |
7373
| [Load Balancing][sample-load-balancing] | Priority and weighted load balancing across backends. | apim-aca, afd-apim-pe |
74+
| [OAuth 3rd-Party][sample-oauth-3rd-party] | Authenticate with APIM which then uses its Credential Manager with Spotify's REST API. | All infrastructures |
7475
| [Secure Blob Access][sample-secure-blob-access] | Secure blob access via the [valet key pattern][valet-key-pattern]. | All infrastructures |
7576
</details>
7677

@@ -381,6 +382,7 @@ _For much more API Management content, please also check out [APIM Love](https:/
381382
[sample-costing]: ./samples/costing/README.md
382383
[sample-general]: ./samples/general/README.md
383384
[sample-load-balancing]: ./samples/load-balancing/README.md
385+
[sample-egress-control]: ./samples/egress-control/README.md
384386
[sample-oauth-3rd-party]: ./samples/oauth-3rd-party/README.md
385387
[sample-secure-blob-access]: ./samples/secure-blob-access/README.md
386388
[simon-kurtz]: https://github.com/simonkurtz-msft

assets/APIM-Samples-Slide-Deck.html

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,7 @@ <h3>&#128218; Samples</h3>
10151015
<ul style="list-style: none; padding: 0;">
10161016
<li style="padding: 6px 0; font-size: 15px; color: #444; display: flex; gap: 10px; align-items: flex-start;">
10171017
<div class="bullet" style="flex-shrink:0; width:8px; height:8px; border-radius:50%; background:#0078D4; margin-top:7px;"></div>
1018-
<div>8 real-world scenarios covering auth, costing, mapping, and more</div>
1018+
<div>9 real-world scenarios covering auth, networking, costing, and more</div>
10191019
</li>
10201020
<li style="padding: 6px 0; font-size: 15px; color: #444; display: flex; gap: 10px; align-items: flex-start;">
10211021
<div class="bullet" style="flex-shrink:0; width:8px; height:8px; border-radius:50%; background:#0078D4; margin-top:7px;"></div>
@@ -1095,18 +1095,18 @@ <h4>App Gateway & APIM (VNet Injection)</h4>
10951095
<div class="slide slide-light">
10961096
<div class="header-bar">
10971097
<div class="accent"></div>
1098-
<h2>8 Real-World Policy Samples</h2>
1098+
<h2>9 Real-World Policy Samples</h2>
10991099
</div>
1100-
<p class="subtitle">From authentication & authorization to cost tracking and secure access patterns</p>
1100+
<p class="subtitle">From authentication &amp; authorization to network routing, cost tracking, and secure access patterns</p>
11011101

1102-
<div class="arch-grid" style="flex: 1;">
1102+
<div class="arch-grid" style="flex: 1; grid-template-columns: 1fr 1fr 1fr;">
11031103
<div class="arch-card">
11041104
<h4>General</h4>
1105-
<p>Basic APIM setup & policy usage. Perfect starting point.</p>
1105+
<p>Basic APIM setup &amp; policy usage. Perfect starting point.</p>
11061106
</div>
11071107
<div class="arch-card">
11081108
<h4>AuthX</h4>
1109-
<p>JWT authentication & role-based authorization with a mock HR API.</p>
1109+
<p>JWT authentication &amp; role-based authorization with a mock HR API.</p>
11101110
</div>
11111111
<div class="arch-card">
11121112
<h4>AuthX Pro</h4>
@@ -1117,16 +1117,20 @@ <h4>Azure Maps</h4>
11171117
<p>Proxying calls to Azure Maps through APIM policies.</p>
11181118
</div>
11191119
<div class="arch-card">
1120-
<h4>Costing & Showback</h4>
1121-
<p>Track API costs per business unit via subscriptions & Log Analytics.</p>
1120+
<h4>Costing &amp; Showback</h4>
1121+
<p>Track API costs per business unit via subscriptions &amp; Log Analytics.</p>
11221122
</div>
11231123
<div class="arch-card">
11241124
<h4>Credential Manager</h4>
11251125
<p>APIM Credential Manager with Spotify's REST API.</p>
11261126
</div>
11271127
<div class="arch-card">
11281128
<h4>Load Balancing</h4>
1129-
<p>Priority & weighted load balancing across backends.</p>
1129+
<p>Priority &amp; weighted load balancing across backends.</p>
1130+
</div>
1131+
<div class="arch-card">
1132+
<h4>Egress Control</h4>
1133+
<p>Route APIM outbound traffic through Azure Firewall in a hub/spoke topology.</p>
11301134
</div>
11311135
<div class="arch-card">
11321136
<h4>Secure Blob Access</h4>
@@ -1414,7 +1418,7 @@ <h4 style="color: #50E6FF;">Educate</h4>
14141418
<div class="summary-item">
14151419
<div class="big-icon">&#9889;</div>
14161420
<h4 style="color: #50E6FF;">Empower</h4>
1417-
<p>8 real-world samples with guided Jupyter notebooks and à la carte flexibility.</p>
1421+
<p>9 real-world samples with guided Jupyter notebooks and à la carte flexibility.</p>
14181422
</div>
14191423
<div class="summary-item">
14201424
<div class="big-icon">&#128640;</div>

0 commit comments

Comments
 (0)