Skip to content

Commit 40b761c

Browse files
Add Boilerplate Sample Setup (#4)
1 parent 4313838 commit 40b761c

File tree

18 files changed

+438
-89
lines changed

18 files changed

+438
-89
lines changed

.gitignore

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ env/
99
# Jupyter
1010
.ipynb_checkpoints/
1111

12-
# VS Code
13-
.vscode/
14-
1512
# Azure
1613
.azure/
1714

@@ -26,7 +23,8 @@ labs-in-progress/
2623
# Exclude sensitive or generated files
2724
.env
2825

29-
3026
# Coverage data and reports
3127
.coverage
3228
tests/python/htmlcov/
29+
30+
shared/bicep/modules/**/*.json

.vscode/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## Fixing Pylance unresolved import warnings
2+
3+
Follow [this documentation](https://github.com/microsoft/pylance-release/blob/main/TROUBLESHOOTING.md#unresolved-import-warnings).

.vscode/settings.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"python.analysis.extraPaths": [
3+
"${workspaceFolder}/shared/python"
4+
],
5+
"python.analysis.completeFunctionParens": true,
6+
"python.analysis.autoIndent": true,
7+
"python.analysis.diagnosticSeverityOverrides": {
8+
"reportDuplicateImport": "warning",
9+
"reportUndefinedVariable": "information",
10+
"reportUnusedVariable": "information"
11+
},
12+
"python.envFile": "${workspaceFolder}/.env",
13+
"plantuml.render": "Local",
14+
"plantuml.exportFormat": "svg",
15+
"terminal.integrated.env.windows": {
16+
"PATH": "${env:PATH}"
17+
},
18+
"plantuml.java": "C:\\Program Files\\OpenJDK\\jdk-22.0.2\\bin\\java.exe",
19+
"plantuml.diagramsRoot": "diagrams/src",
20+
"plantuml.exportOutDir": "diagrams/out"
21+
}

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,18 @@ The first time you run a Jupyter notebook, you'll be asked to install the Jupyte
7979

8080
Now that infrastructure and sample have been stood up, you can experiment with the policies, make requests against APIM, etc.
8181

82+
### Adding a Sample
83+
84+
Adding a new sample is relatively straight-forward.
85+
86+
1. Create a new feature branch for the new sample.
87+
1. Copy the `/samples/_TEMPLATE` folder.
88+
1. Rename the copied folder to a name representative of the sample (e.g. "load-balancing", "authX", etc.)
89+
1. Change the `create.ipynb` and `main.bicep` files. Look for the brackets (`[ ]`) brackets for specific inputs.
90+
1. Add any policy.xml files to the same folder if they are specific to this sample. If they are to be reused, place them into the `/shared/apim-policies` folder instead.
91+
1. Test the sample with all supported infrastructures.
92+
1. Create a pull request for merge.
93+
8294
---
8395

8496
## Development
@@ -89,7 +101,6 @@ The repo uses the bicep linter and has rules defined in `bicepconfig.json`. See
89101

90102
We welcome contributions! Please consider forking the repo and creating issues and pull requests to share your samples. Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details. Thank you!
91103

92-
93104
### Testing & Code Coverage
94105

95106
Python modules in `shared/python` are covered by comprehensive unit tests located in `tests/python`. All tests use [pytest](https://docs.pytest.org/) and leverage modern pytest features, including custom markers for unit and HTTP tests.

infrastructure/afd-apim/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
# Front Door & API Management & Container Apps Infrastructure
32

43
Secure architecture that takes all traffic off the public Internet once Azure Front Door is traversed. This is due to Front Door's use of a private link to Azure API Management.

infrastructure/afd-apim/create.ipynb

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,11 @@
4545
"# 3) Define the APIs and their operations and policies\n",
4646
"\n",
4747
"# Policies\n",
48-
"default_policy_xml = utils.policy_xml_replacement(DEFAULT_XML_POLICY_PATH)\n",
4948
"hello_world_policy_xml = utils.policy_xml_replacement(HELLO_WORLD_XML_POLICY_PATH)\n",
5049
"\n",
5150
"# Hello World (Root)\n",
5251
"api_hwroot_get = GET_APIOperation('This is a GET for API 1', hello_world_policy_xml)\n",
53-
"api_hwroot = API('hello-world', 'Hello World', '', 'This is the root API for Hello World', default_policy_xml, [api_hwroot_get])\n",
52+
"api_hwroot = API('hello-world', 'Hello World', '', 'This is the root API for Hello World', operations = [api_hwroot_get])\n",
5453
"\n",
5554
"apis: List[API] = [api_hwroot]\n",
5655
"\n",
@@ -63,16 +62,16 @@
6362
" aca_backend_pool_policy_xml = utils.policy_xml_replacement(ACA_BACKEND_POOL_XML_POLICY_PATH)\n",
6463
"\n",
6564
" # Hello World (ACA Backend 1)\n",
66-
" api_hwaca_1_get = GET_APIOperation('This is a GET for Hello World on ACA Backend 1', default_policy_xml)\n",
67-
" api_hwaca_1 = API('hello-world-aca-1', 'Hello World (ACA 1)', '/aca-1', 'This is the ACA API for Backend 1', aca_backend_1_policy_xml, [api_hwaca_1_get])\n",
65+
" api_hwaca_1_get = GET_APIOperation('This is a GET for Hello World on ACA Backend 1')\n",
66+
" api_hwaca_1 = API('hello-world-aca-1', 'Hello World (ACA 1)', '/aca-1', 'This is the ACA API for Backend 1', policyXml = aca_backend_1_policy_xml, operations = [api_hwaca_1_get])\n",
6867
"\n",
6968
" # Hello World (ACA Backend 2)\n",
70-
" api_hwaca_2_get = GET_APIOperation('This is a GET for Hello World on ACA Backend 2', default_policy_xml)\n",
71-
" api_hwaca_2 = API('hello-world-aca-2', 'Hello World (ACA 2)', '/aca-2', 'This is the ACA API for Backend 2', aca_backend_2_policy_xml, [api_hwaca_2_get])\n",
69+
" api_hwaca_2_get = GET_APIOperation('This is a GET for Hello World on ACA Backend 2')\n",
70+
" api_hwaca_2 = API('hello-world-aca-2', 'Hello World (ACA 2)', '/aca-2', 'This is the ACA API for Backend 2', policyXml = aca_backend_2_policy_xml, operations = [api_hwaca_2_get])\n",
7271
"\n",
7372
" # Hello World (ACA Backend Pool)\n",
74-
" api_hwaca_pool_get = GET_APIOperation('This is a GET for Hello World on ACA Backend Pool', default_policy_xml)\n",
75-
" api_hwaca_pool = API('hello-world-aca-pool', 'Hello World (ACA Pool)', '/aca-pool', 'This is the ACA API for Backend Pool', aca_backend_pool_policy_xml, [api_hwaca_pool_get])\n",
73+
" api_hwaca_pool_get = GET_APIOperation('This is a GET for Hello World on ACA Backend Pool')\n",
74+
" api_hwaca_pool = API('hello-world-aca-pool', 'Hello World (ACA Pool)', '/aca-pool', 'This is the ACA API for Backend Pool', policyXml = aca_backend_pool_policy_xml, operations = [api_hwaca_pool_get])\n",
7675
"\n",
7776
" # Add ACA APIs to the existing apis array\n",
7877
" apis += [api_hwaca_1, api_hwaca_2, api_hwaca_pool]\n",
@@ -111,7 +110,7 @@
111110
"\n",
112111
"# 3) Print a deployment summary, if successful; otherwise, exit with an error\n",
113112
"if not output.success:\n",
114-
" exit('Deployment failed')\n",
113+
" raise SystemExit('Deployment failed')\n",
115114
"\n",
116115
"if output.success and output.json_data:\n",
117116
" apim_service_id = output.get('apimServiceId', 'APIM Service Id')\n",
@@ -219,7 +218,7 @@
219218
"\n",
220219
"# 3) Print a single, clear deployment summary if successful\n",
221220
"if not output.success:\n",
222-
" exit('Deployment failed')\n",
221+
" raise SystemExit('Deployment failed')\n",
223222
" \n",
224223
"if output.success and output.json_data:\n",
225224
" apim_gateway_url = output.get('apimResourceGatewayURL', 'APIM API Gateway URL')\n",

infrastructure/apim-aca/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
# API Management & Container Apps Infrastructure
32

43
This architecture secures API traffic by routing requests through Azure API Management, which is integrated with Azure Container Apps for backend processing. Telemetry is sent to Azure Monitor for observability.

infrastructure/apim-aca/create.ipynb

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,27 +45,26 @@
4545
"# 3) Define the APIs and their operations and policies\n",
4646
"\n",
4747
"# Policies\n",
48-
"default_policy_xml = utils.policy_xml_replacement(DEFAULT_XML_POLICY_PATH)\n",
4948
"hello_world_policy_xml = utils.policy_xml_replacement(HELLO_WORLD_XML_POLICY_PATH)\n",
5049
"aca_backend_1_policy_xml = utils.policy_xml_replacement(ACA_BACKEND_1_XML_POLICY_PATH)\n",
5150
"aca_backend_2_policy_xml = utils.policy_xml_replacement(ACA_BACKEND_2_XML_POLICY_PATH)\n",
5251
"aca_backend_pool_policy_xml = utils.policy_xml_replacement(ACA_BACKEND_POOL_XML_POLICY_PATH)\n",
5352
"\n",
5453
"# Hello World (Root)\n",
5554
"api_hwroot_get = GET_APIOperation('This is a GET for Hello World in the root', hello_world_policy_xml)\n",
56-
"api_hwroot = API('hello-world', 'Hello World', '', 'This is the root API for Hello World', default_policy_xml, [api_hwroot_get])\n",
55+
"api_hwroot = API('hello-world', 'Hello World', '', 'This is the root API for Hello World', operations = [api_hwroot_get])\n",
5756
"\n",
5857
"# Hello World (ACA Backend 1)\n",
59-
"api_hwaca_1_get = GET_APIOperation('This is a GET for Hello World on ACA Backend 1', default_policy_xml)\n",
60-
"api_hwaca_1 = API('hello-world-aca-1', 'Hello World (ACA 1)', '/aca-1', 'This is the ACA API for Backend 1', aca_backend_1_policy_xml, [api_hwaca_1_get])\n",
58+
"api_hwaca_1_get = GET_APIOperation('This is a GET for Hello World on ACA Backend 1')\n",
59+
"api_hwaca_1 = API('hello-world-aca-1', 'Hello World (ACA 1)', '/aca-1', 'This is the ACA API for Backend 1', policyXml = aca_backend_1_policy_xml, operations = [api_hwaca_1_get])\n",
6160
"\n",
6261
"# Hello World (ACA Backend 2)\n",
63-
"api_hwaca_2_get = GET_APIOperation('This is a GET for Hello World on ACA Backend 2', default_policy_xml)\n",
64-
"api_hwaca_2 = API('hello-world-aca-2', 'Hello World (ACA 2)', '/aca-2', 'This is the ACA API for Backend 2', aca_backend_2_policy_xml, [api_hwaca_2_get])\n",
62+
"api_hwaca_2_get = GET_APIOperation('This is a GET for Hello World on ACA Backend 2')\n",
63+
"api_hwaca_2 = API('hello-world-aca-2', 'Hello World (ACA 2)', '/aca-2', 'This is the ACA API for Backend 2', policyXml = aca_backend_2_policy_xml, operations = [api_hwaca_2_get])\n",
6564
"\n",
6665
"# Hello World (ACA Backend Pool)\n",
67-
"api_hwaca_pool_get = GET_APIOperation('This is a GET for Hello World on ACA Backend Pool', default_policy_xml)\n",
68-
"api_hwaca_pool = API('hello-world-aca-pool', 'Hello World (ACA Pool)', '/aca-pool', 'This is the ACA API for Backend Pool', aca_backend_pool_policy_xml, [api_hwaca_pool_get])\n",
66+
"api_hwaca_pool_get = GET_APIOperation('This is a GET for Hello World on ACA Backend Pool')\n",
67+
"api_hwaca_pool = API('hello-world-aca-pool', 'Hello World (ACA Pool)', '/aca-pool', 'This is the ACA API for Backend Pool', policyXml = aca_backend_pool_policy_xml, operations = [api_hwaca_pool_get])\n",
6968
"\n",
7069
"# APIs Array\n",
7170
"apis: List[API] = [api_hwroot, api_hwaca_1, api_hwaca_2, api_hwaca_pool]\n",
@@ -101,7 +100,7 @@
101100
"\n",
102101
"# 3) Check the deployment outputs\n",
103102
"if not output.success:\n",
104-
" exit('Deployment failed')\n",
103+
" raise SystemExit('Deployment failed')\n",
105104
"\n",
106105
"if output.success and output.json_data:\n",
107106
" apim_gateway_url = output.get('apimResourceGatewayURL', 'APIM API Gateway URL')\n",

infrastructure/simple-apim/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
# Simple API Management Infrastructure
32

43
This architecture provides a basic API gateway using Azure API Management, suitable for simple scenarios where secure API exposure and basic observability are required.

infrastructure/simple-apim/create.ipynb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,11 @@
4343
"# 3) Define the APIs and their operations and policies\n",
4444
"\n",
4545
"# Policies\n",
46-
"default_policy_xml = utils.policy_xml_replacement(DEFAULT_XML_POLICY_PATH)\n",
4746
"hello_world_policy_xml = utils.policy_xml_replacement(HELLO_WORLD_XML_POLICY_PATH)\n",
4847
"\n",
4948
"# Hello World (Root)\n",
5049
"api_hwroot_get = GET_APIOperation('This is a GET for API 1', hello_world_policy_xml)\n",
51-
"api_hwroot = API('hello-world', 'Hello World', '', 'This is the root API for Hello World', default_policy_xml, [api_hwroot_get])\n",
50+
"api_hwroot = API('hello-world', 'Hello World', '', 'This is the root API for Hello World', operations = [api_hwroot_get])\n",
5251
"\n",
5352
"# APIs Array\n",
5453
"apis: List[API] = [api_hwroot]\n",
@@ -84,7 +83,7 @@
8483
"\n",
8584
"# 3) Check the deployment outputs\n",
8685
"if not output.success:\n",
87-
" exit('Deployment failed')\n",
86+
" raise SystemExit('Deployment failed')\n",
8887
"\n",
8988
"if output.success and output.json_data:\n",
9089
" apim_gateway_url = output.get('apimResourceGatewayURL', 'APIM API Gateway URL')\n",

0 commit comments

Comments
 (0)