-
Notifications
You must be signed in to change notification settings - Fork 28
Add proxy to Azure Maps #63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 23 commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
3bdfa1c
Add Azure Maps integration with APIM, including policies and Bicep co…
anotherRedbeard 3879831
Enhance Azure Maps integration by implementing user-assigned managed …
anotherRedbeard 5feb2c1
Merge branch 'main' into ar/azure-maps
simonkurtz-MSFT a6cf6e3
Fix policy XML read
simonkurtz-MSFT cc146c4
Update Azure Maps sample documentation and enhance async request hand…
anotherRedbeard 7fd2671
Merge branch 'ar/azure-maps' of https://github.com/Azure-Samples/Apim…
anotherRedbeard b191db1
Add Azure Maps integration with APIM, including policies and Bicep co…
anotherRedbeard 816abf8
Enhance Azure Maps integration by implementing user-assigned managed …
anotherRedbeard 8d3c32a
Update Azure Maps sample documentation and enhance async request hand…
anotherRedbeard c62e458
Fix policy XML read
simonkurtz-MSFT 4a5a829
wqMerge branch 'ar/azure-maps' of https://github.com/Azure-Samples/Ap…
anotherRedbeard 79d4d85
Enhance Azure Maps sample notebook and Bicep templates
anotherRedbeard 5a611bd
Remove output logs from Azure Maps sample notebook to streamline exec…
anotherRedbeard 0637718
Add Azure Maps integration with APIM, including policies and Bicep co…
anotherRedbeard 66b93f7
Enhance Azure Maps integration by implementing user-assigned managed …
anotherRedbeard eeb36f8
Update Azure Maps sample documentation and enhance async request hand…
anotherRedbeard fb8c244
Fix policy XML read
simonkurtz-MSFT a3c23ec
Enhance Azure Maps sample notebook and Bicep templates
anotherRedbeard 8c1b9ad
Remove output logs from Azure Maps sample notebook to streamline exec…
anotherRedbeard dba0707
Merge branch 'ar/azure-maps' of https://github.com/Azure-Samples/Apim…
anotherRedbeard 7c026fa
Refactor Azure Maps sample notebook and Bicep templates for improved …
anotherRedbeard 7232be5
Merge branch 'main' into ar/azure-maps
anotherRedbeard b88cacf
Fix function call for Bicep deployment in Azure Maps sample notebook
anotherRedbeard 93ef931
Enhance Azure Maps sample notebook and Bicep templates with improved …
anotherRedbeard 61b4f12
Merge branch 'main' into ar/azure-maps
simonkurtz-MSFT 80e47b8
Update README.md to enhance Azure Maps sample documentation with deta…
anotherRedbeard 2f939c9
Add refactoring changes
simonkurtz-MSFT 26f947f
Update test initialization and add preflight check for Azure Maps sample
anotherRedbeard 5b39ce5
Use the determined endpoint URL in tests
simonkurtz-MSFT File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # Samples: Api Management proxing calls to Azure Maps | ||
|
|
||
| This is a sample demonstrating how to use Azure API Management (APIM) to proxy calls to the Azure Maps service. This setup allows you to manage, secure, and monitor access to Azure Maps through APIM. | ||
|
|
||
| ⚙️ **Supported infrastructures**: All infrastructures | ||
|
|
||
| 👟 **Expected *Run All* runtime (excl. infrastructure prerequisite): ~[NOTEBOOK RUNTIME] minute** | ||
|
|
||
| ## 🎯 Objectives | ||
|
|
||
| 1. Learn how to set up APIM to proxy requests to Azure Maps on a path to operation based mapping. | ||
| 1. Learn how to set up APIM to proxy requests to Azure Maps on a generic path. | ||
| 1. See how to secure access to Azure Maps using APIM policies for all 3 authentication methods (subscription key, Azure Entra AD, and SAS Tokens). | ||
| 1. Show how to connect to the v1 enpoint of Azure Maps using APIM. | ||
|
|
||
| ## 📝 Scenario | ||
|
|
||
| This sample demonstrates how to use APIM to proxy requests to the Azure Maps service. By doing so, you can leverage APIM's capabilities to manage, secure, and monitor access to Azure Maps. This particular setup will show you how to map specific paths to Azure Maps APIs, as well as how to handle generic paths. Additionally, the sample will illustrate how to secure access to Azure Maps using different authentication methods supported by APIM policies. | ||
|
|
||
| ## 🛩️ Lab Components | ||
|
|
||
| This lab sets up: | ||
|
|
||
| - An Azure Maps resource in Azure | ||
| - APIM managed identity with the following roles: | ||
| - **Azure Maps Search and Render Data Reader:** Grants the ability to call the apis and render the maps | ||
| - **Azure Maps Contributor:** Grants the ability to create the SAS Token from the APIM policy | ||
| - A User Assigned Managed Identity (UAMI) that is used as the principal id to emulate when creating the SAS Token for Azure Maps. It has the following roles asigned: | ||
| - **Azure Maps Search and Render Data Reader:** Grants the ability to call the apis and render the maps | ||
| - An API that demonstrates proxying requests to Azure Maps specific to APIs (geocode, search, etc.) | ||
| - Also in that api there will be an operation that demonstrates a generic path to Azure Maps | ||
|
|
||
| ## ⚙️ Configuration | ||
|
|
||
| 1. Decide which of the [Infrastructure Architectures](../../README.md#infrastructure-architectures) you wish to use. | ||
| 1. If the infrastructure _does not_ yet exist, navigate to the desired [infrastructure](../../infrastructure/) folder and follow its README.md. | ||
| 1. If the infrastructure _does_ exist, adjust the `user-defined parameters` in the _Initialize notebook variables_ below. Please ensure that all parameters match your infrastructure. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,166 @@ | ||
| { | ||
| "cells": [ | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "### 🛠️ 1. Initialize notebook variables\n", | ||
| "\n", | ||
| "Configures everything that's needed for deployment. \n", | ||
| "\n", | ||
| "**Modify entries under _1) User-defined parameters_ and _3) Define the APIs and their operations and policies_**." | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "metadata": {}, | ||
| "outputs": [], | ||
| "source": [ | ||
| "import utils\n", | ||
| "from apimtypes import *\n", | ||
| "\n", | ||
| "# 1) User-defined parameters (change these as needed)\n", | ||
| "rg_location = 'eastus2'\n", | ||
| "index = 1\n", | ||
| "deployment = INFRASTRUCTURE.SIMPLE_APIM\n", | ||
| "tags = ['azure-maps'] # ENTER DESCRIPTIVE TAG(S)\n", | ||
| "api_prefix = 'am-' # OPTIONAL: ENTER A PREFIX FOR THE APIS TO REDUCE COLLISION POTENTIAL WITH OTHER SAMPLES\n", | ||
| "azure_maps_url = 'https://atlas.microsoft.com' # OPTIONAL: ENTER THE AZURE MAPS URL IF DIFFERENT FROM DEFAULT\n", | ||
|
simonkurtz-MSFT marked this conversation as resolved.
|
||
| "\n", | ||
| "# 2) Service-defined parameters (please do not change these)\n", | ||
| "rg_name = utils.get_infra_rg_name(deployment, index)\n", | ||
| "supported_infrastructures = [INFRASTRUCTURE.SIMPLE_APIM, INFRASTRUCTURE.AFD_APIM_PE, INFRASTRUCTURE.APIM_ACA] # ENTER SUPPORTED INFRASTRUCTURES HERE, e.g., [INFRASTRUCTURE.AFD_APIM_PE, INFRASTRUCTURE.AFD_APIM_FE]\n", | ||
| "utils.validate_infrastructure(deployment, supported_infrastructures)\n", | ||
| "sample_folder = \"azure-maps\"\n", | ||
| "# 3) Define the APIs and their operations and policies\n", | ||
| "\n", | ||
| "# Policies\n", | ||
| "# Named values must be set up a bit differently as they need to have two surrounding curly braces\n", | ||
| "map_async_geocode_batch_v1_keyauth_post_xml = utils.read_policy_xml('map_async_geocode_batch_v1_keyauth_post.xml', sample_name=sample_folder)\n", | ||
| "map_default_route_v2_aad_get_xml = utils.read_policy_xml('map_default_route_v2_aad_get.xml', sample_name=sample_folder)\n", | ||
| "map_geocode_v2_aad_get_xml = utils.read_policy_xml('map_geocode_v2_aad_get.xml', sample_name=sample_folder)\n", | ||
| "\n", | ||
| "# Map API \n", | ||
| "mapApi_v2_default_get = GET_APIOperation2('get-default-route','Get default route','/default/*','This is the default route that will allow all requests to go through to the backend api',map_default_route_v2_aad_get_xml)\n", | ||
| "mapApi_v1_async_post = APIOperation('async-geocode-batch','Async Geocode Batch','/geocode/batch/async',HTTP_VERB.POST, 'Post geocode batch async endpoint',map_async_geocode_batch_v1_keyauth_post_xml)\n", | ||
| "mapApi_v2_geocode_get = GET_APIOperation2('get-geocode','Get Geocode','/geocode','Get geocode endpoint',map_geocode_v2_aad_get_xml)\n", | ||
| "api1 = API('map-api', 'Map API', '/map', 'This is the proxy for Azure Maps', operations=[mapApi_v2_default_get, mapApi_v1_async_post,mapApi_v2_geocode_get], tags = tags, serviceUrl=azure_maps_url)\n", | ||
| "\n", | ||
| "# APIs Array\n", | ||
| "# apis: List[API] = [api1, apin]\n", | ||
| "apis: List[API] = [api1]\n", | ||
| "\n", | ||
| "# 4) Set up the named values, for this specific sample, we are using some of the named values in the API policies defined above that can't be known at this point in the process. For those named values, we are setting them in the main.bicep file.\n", | ||
| "nvs: List[NamedValue] = [\n", | ||
| " NamedValue('azure-maps-arm-api-version','2023-06-01')\n", | ||
| "]\n", | ||
| "\n", | ||
| "utils.print_ok('Notebook initialized')" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "### 🚀 2. Create deployment using Bicep\n", | ||
| "\n", | ||
| "Creates the bicep deployment into the previously-specified resource group. A bicep parameters file will be created prior to execution." | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "metadata": {}, | ||
| "outputs": [], | ||
| "source": [ | ||
| "import utils\n", | ||
| "\n", | ||
| "# 1) Define the Bicep parameters with serialized APIs\n", | ||
| "bicep_parameters = {\n", | ||
| " 'apis': {'value': [api.to_dict() for api in apis]},\n", | ||
| " 'namedValues': {'value': [nv.to_dict() for nv in nvs]}\n", | ||
| "}\n", | ||
| "\n", | ||
| "# 2) Infrastructure must be in place before samples can be layered on top\n", | ||
| "if not utils.does_resource_group_exist(rg_name):\n", | ||
| " utils.print_error(f'The specified infrastructure resource group and its resources must exist first. Please check that the user-defined parameters above are correctly referencing an existing infrastructure. If it does not yet exist, run the desired infrastructure in the /infra/ folder first.')\n", | ||
| " raise SystemExit(1)\n", | ||
| "\n", | ||
| "# 3) Run the deployment\n", | ||
| "output = utils.create_bicep_deployment_group_for_sample(sample_folder, rg_name, rg_location, bicep_parameters)\n", | ||
| "\n", | ||
| "# 4) Print a deployment summary, if successful; otherwise, exit with an error\n", | ||
| "if not output.success:\n", | ||
| " raise SystemExit('Deployment failed')\n", | ||
| "\n", | ||
| "if output.success and output.json_data:\n", | ||
| " apim_gateway_url = output.get('apimResourceGatewayURL', 'APIM API Gateway URL')\n", | ||
| "\n", | ||
| "utils.print_ok('Deployment completed')" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "markdown", | ||
| "metadata": {}, | ||
| "source": [ | ||
| "### ✅ 3. Verify API Request Success\n", | ||
| "\n", | ||
| "Assert that the deployment was successful by making simple calls to APIM. \n", | ||
| "\n", | ||
| "❗️ If the infrastructure shields APIM and requires a different ingress (e.g. Azure Front Door), the request to the APIM gateway URl will fail by design. Obtain the Front Door endpoint hostname and try that instead." | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "metadata": {}, | ||
| "outputs": [], | ||
| "source": [ | ||
| "import utils\n", | ||
| "from apimrequests import ApimRequests\n", | ||
| "\n", | ||
| "reqs = ApimRequests(apim_gateway_url)\n", | ||
| "\n", | ||
| "# 1) Issue a direct request to API Management\n", | ||
|
simonkurtz-MSFT marked this conversation as resolved.
|
||
| "reqs.singleGet('/', msg = 'Calling Hello World (Root) API. Expect 200.')\n", | ||
| "\n", | ||
| "# 2) Issue requests to API Management with Azure Maps APIs\n", | ||
| "reqs.singleGet('/map/default/geocode?query=15127%20NE%2024th%20Street%20Redmond%20WA', msg = 'Calling Default Route API with SAS Token Auth. Expect 200.')\n", | ||
| "reqs.singleGet('/map/geocode?query=15127%20NE%2024th%20Street%20Redmond%20WA', msg = 'Calling Geocode v2 API with AAD Auth. Expect 200.')\n", | ||
| "reqs.singlePostAsync('/map/geocode/batch/async', data={\n", | ||
| " \"batchItems\": [\n", | ||
| " {\"query\": \"?query=400 Broad St, Seattle, WA 98109&limit=3\"},\n", | ||
| " {\"query\": \"?query=One, Microsoft Way, Redmond, WA 98052&limit=3\"},\n", | ||
| " {\"query\": \"?query=350 5th Ave, New York, NY 10118&limit=1\"},\n", | ||
| " {\"query\": \"?query=Pike Pl, Seattle, WA 98101&lat=47.610970&lon=-122.342469&radius=1000\"},\n", | ||
| " {\"query\": \"?query=Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France&limit=1\"}\n", | ||
| " ]\n", | ||
| "}, msg = 'Calling Async Geocode Batch v1 API with Share Key Auth. Expect initial 202, then a 200 on the polling response', timeout=120, poll_interval=3)\n", | ||
| "\n", | ||
| "utils.print_ok('All done!')" | ||
| ] | ||
| } | ||
| ], | ||
| "metadata": { | ||
| "kernelspec": { | ||
| "display_name": ".venv", | ||
| "language": "python", | ||
| "name": "python3" | ||
| }, | ||
| "language_info": { | ||
| "codemirror_mode": { | ||
| "name": "ipython", | ||
| "version": 3 | ||
| }, | ||
| "file_extension": ".py", | ||
| "mimetype": "text/x-python", | ||
| "name": "python", | ||
| "nbconvert_exporter": "python", | ||
| "pygments_lexer": "ipython3", | ||
| "version": "3.12.11" | ||
| } | ||
| }, | ||
| "nbformat": 4, | ||
| "nbformat_minor": 2 | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.