Skip to content

Commit a4ea160

Browse files
Milestone 1.8.0/bug fixes (#83)
1 parent c6e17ce commit a4ea160

28 files changed

+2602
-1412
lines changed

.github/.copilot-instructions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ In case of any conflicting instructions, the following hierarchy shall apply. If
5151
- Break down complex logic into smaller, manageable functions or classes.
5252
- Use type annotations and docstrings where appropriate.
5353
- Prefer standard libraries and well-maintained dependencies.
54+
- Use samples/_TEMPLATE as a baseline for new samples. This template provides a consistent structure and format for new samples, ensuring they are easy to understand and maintain.
5455

5556
## Repository Structure
5657

infrastructure/afd-apim-pe/create.ipynb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@
5252
],
5353
"metadata": {
5454
"kernelspec": {
55-
"display_name": ".venv (3.12.10)",
55+
"display_name": "APIM Samples Python 3.12",
5656
"language": "python",
57-
"name": "python3"
57+
"name": "apim-samples"
5858
},
5959
"language_info": {
6060
"codemirror_mode": {

infrastructure/afd-apim-pe/create_infrastructure.py

Lines changed: 48 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ def _create_afd_apim_pe_infrastructure(
4242
rg_tags = utils.build_infrastructure_tags(deployment)
4343
apim_network_mode = APIMNetworkMode.EXTERNAL_VNET
4444

45-
print(f"\n🚀 Creating AFD-APIM-PE infrastructure...")
46-
print(f" Location : {rg_location}")
47-
print(f" Index : {index}")
48-
print(f" Infrastructure : {deployment.value}")
49-
print(f" APIM SKU : {apim_sku.value}")
50-
print(f" Use ACA : {use_aca}")
51-
print(f" Resource Group : {rg_name}\n")
45+
print(f'\n🚀 Creating AFD-APIM-PE infrastructure...')
46+
print(f' Location : {rg_location}')
47+
print(f' Index : {index}')
48+
print(f' Infrastructure : {deployment.value}')
49+
print(f' APIM SKU : {apim_sku.value}')
50+
print(f' Use ACA : {use_aca}')
51+
print(f' Resource Group : {rg_name}\n')
5252

5353
# 2) Set up the policy fragments
5454
if custom_policy_fragments is None:
@@ -109,62 +109,62 @@ def _create_afd_apim_pe_infrastructure(
109109

110110
try:
111111
os.chdir(infra_dir)
112-
print(f"📁 Changed working directory to: {infra_dir}")
112+
print(f'📁 Changed working directory to: {infra_dir}')
113113

114114
# 6) Create the resource group if it doesn't exist
115115
utils.create_resource_group(rg_name, rg_location, rg_tags)
116116

117117
# 7) First deployment with public access enabled
118-
print("\n🚀 Phase 1: Creating infrastructure with public access enabled...")
118+
print('\n🚀 Phase 1: Creating infrastructure with public access enabled...')
119119
output = utils.create_bicep_deployment_group(rg_name, rg_location, deployment, bicep_parameters)
120120

121121
if not output.success:
122-
print("❌ Phase 1 deployment failed!")
122+
print('❌ Phase 1 deployment failed!')
123123
return output
124124

125125
# Extract service details for private link approval
126126
if output.json_data:
127127
apim_service_id = output.get('apimServiceId', 'APIM Service Id', suppress_logging = True)
128128

129-
print("✅ Phase 1 deployment completed successfully!")
129+
print('✅ Phase 1 deployment completed successfully!')
130130

131131
# 8) Approve private link connections
132-
print("\n🔗 Approving Front Door private link connections...")
132+
print('\n🔗 Approving Front Door private link connections...')
133133
_approve_private_link_connections(apim_service_id)
134134

135135
# 9) Second deployment to disable public access
136-
print("\n🔒 Phase 2: Disabling APIM public access...")
136+
print('\n🔒 Phase 2: Disabling APIM public access...')
137137
bicep_parameters['apimPublicAccess']['value'] = False
138138

139139
output = utils.create_bicep_deployment_group(rg_name, rg_location, deployment, bicep_parameters)
140140

141141
if output.success:
142-
print("\n✅ Infrastructure creation completed successfully!")
142+
print('\n✅ Infrastructure creation completed successfully!')
143143
if output.json_data:
144144
apim_gateway_url = output.get('apimResourceGatewayURL', 'APIM API Gateway URL', suppress_logging = True)
145145
afd_endpoint_url = output.get('fdeSecureUrl', 'Front Door Endpoint URL', suppress_logging = True)
146146
apim_apis = output.getJson('apiOutputs', 'APIs', suppress_logging = True)
147147

148-
print(f"\n📋 Infrastructure Details:")
149-
print(f" Resource Group : {rg_name}")
150-
print(f" Location : {rg_location}")
151-
print(f" APIM SKU : {apim_sku.value}")
152-
print(f" Use ACA : {use_aca}")
153-
print(f" Gateway URL : {apim_gateway_url}")
154-
print(f" Front Door URL : {afd_endpoint_url}")
155-
print(f" APIs Created : {len(apim_apis)}")
148+
print(f'\n📋 Infrastructure Details:')
149+
print(f' Resource Group : {rg_name}')
150+
print(f' Location : {rg_location}')
151+
print(f' APIM SKU : {apim_sku.value}')
152+
print(f' Use ACA : {use_aca}')
153+
print(f' Gateway URL : {apim_gateway_url}')
154+
print(f' Front Door URL : {afd_endpoint_url}')
155+
print(f' APIs Created : {len(apim_apis)}')
156156

157157
# Perform basic verification
158-
_verify_infrastructure(rg_name, afd_endpoint_url, apim_gateway_url, use_aca)
158+
_verify_infrastructure(rg_name, use_aca)
159159
else:
160-
print("❌ Phase 2 deployment failed!")
160+
print('❌ Phase 2 deployment failed!')
161161

162162
return output
163163

164164
finally:
165165
# Always restore the original working directory
166166
os.chdir(original_cwd)
167-
print(f"📁 Restored working directory to: {original_cwd}")
167+
print(f'📁 Restored working directory to: {original_cwd}')
168168

169169
def _approve_private_link_connections(apim_service_id: str) -> None:
170170
"""
@@ -175,7 +175,7 @@ def _approve_private_link_connections(apim_service_id: str) -> None:
175175
"""
176176

177177
# Get all pending private endpoint connections as JSON
178-
output = utils.run(f"az network private-endpoint-connection list --id {apim_service_id} --query \"[?contains(properties.privateLinkServiceConnectionState.status, 'Pending')]\" -o json", print_command_to_run = False)
178+
output = utils.run(f"az network private-endpoint-connection list --id {apim_service_id} --query \"[?contains(properties.privateLinkServiceConnectionState.status, 'Pending')]\' -o json', print_command_to_run = False)
179179

180180
# Handle both a single object and a list of objects
181181
pending_connections = output.json_data if output.success and output.is_json else []
@@ -184,80 +184,78 @@ def _approve_private_link_connections(apim_service_id: str) -> None:
184184
pending_connections = [pending_connections]
185185

186186
total = len(pending_connections)
187-
print(f"Found {total} pending private link service connection(s).")
187+
print(f'Found {total} pending private link service connection(s).')
188188

189189
if total > 0:
190190
for i, conn in enumerate(pending_connections, 1):
191191
conn_id = conn.get('id')
192192
conn_name = conn.get('name', '<unknown>')
193-
print(f" {i}/{total}: Approving {conn_name}")
193+
print(f' {i}/{total}: Approving {conn_name}')
194194

195195
approve_result = utils.run(
196196
f"az network private-endpoint-connection approve --id {conn_id} --description 'Approved'",
197-
f"Private Link Connection approved: {conn_name}",
198-
f"Failed to approve Private Link Connection: {conn_name}",
197+
f'Private Link Connection approved: {conn_name}',
198+
f'Failed to approve Private Link Connection: {conn_name}',
199199
print_command_to_run = False
200200
)
201201

202-
print("✅ Private link approvals completed")
202+
print('✅ Private link approvals completed')
203203
else:
204-
print("No pending private link service connections found. Nothing to approve.")
204+
print('No pending private link service connections found. Nothing to approve.')
205205

206-
def _verify_infrastructure(rg_name: str, afd_endpoint_url: str, apim_gateway_url: str, use_aca: bool) -> bool:
206+
def _verify_infrastructure(rg_name: str, use_aca: bool) -> bool:
207207
"""
208208
Verify that the infrastructure was created successfully.
209209
210210
Args:
211211
rg_name (str): Resource group name.
212-
afd_endpoint_url (str): Azure Front Door endpoint URL.
213-
apim_gateway_url (str): API Management gateway URL.
214212
use_aca (bool): Whether Container Apps were included.
215213
216214
Returns:
217215
bool: True if verification passed, False otherwise.
218216
"""
219217

220-
print("\n🔍 Verifying infrastructure...")
218+
print('\n🔍 Verifying infrastructure...')
221219

222220
try:
223221
# Check if the resource group exists
224222
if not utils.does_resource_group_exist(rg_name):
225-
print("❌ Resource group does not exist!")
223+
print('❌ Resource group does not exist!')
226224
return False
227225

228-
print("✅ Resource group verified")
226+
print('✅ Resource group verified')
229227

230228
# Get APIM service details
231-
output = utils.run(f'az apim list -g {rg_name} --query "[0]" -o json', print_command_to_run = False, print_errors = False)
229+
output = utils.run(f'az apim list -g {rg_name} --query '[0]' -o json', print_command_to_run = False, print_errors = False)
232230

233231
if output.success and output.json_data:
234232
apim_name = output.json_data.get('name')
235-
print(f"✅ APIM Service verified: {apim_name}")
233+
print(f'✅ APIM Service verified: {apim_name}')
236234

237235
# Check Front Door
238-
afd_output = utils.run(f'az afd profile list -g {rg_name} --query "[0]" -o json', print_command_to_run = False, print_errors = False)
236+
afd_output = utils.run(f'az afd profile list -g {rg_name} --query '[0]' -o json', print_command_to_run = False, print_errors = False)
239237

240238
if afd_output.success and afd_output.json_data:
241239
afd_name = afd_output.json_data.get('name')
242-
print(f"✅ Azure Front Door verified: {afd_name}")
240+
print(f'✅ Azure Front Door verified: {afd_name}')
243241

244242
# Check Container Apps if enabled
245243
if use_aca:
246-
aca_output = utils.run(f'az containerapp list -g {rg_name} --query "length(@)"', print_command_to_run = False, print_errors = False)
244+
aca_output = utils.run(f'az containerapp list -g {rg_name} --query 'length(@)'', print_command_to_run = False, print_errors = False)
247245

248246
if aca_output.success:
249247
aca_count = int(aca_output.text.strip())
250-
print(f"✅ Container Apps verified: {aca_count} app(s) created")
248+
print(f'✅ Container Apps verified: {aca_count} app(s) created')
251249

252-
print("\n🎉 Infrastructure verification completed successfully!")
250+
print('\n🎉 Infrastructure verification completed successfully!')
253251
return True
254252

255253
else:
256-
print("\n❌ APIM service not found!")
254+
print('\n❌ APIM service not found!')
257255
return False
258256

259257
except Exception as e:
260-
print(f"\n⚠️ Verification failed with error: {str(e)}")
258+
print(f'\n⚠️ Verification failed with error: {str(e)}')
261259
return False
262260

263261
def main():
@@ -288,14 +286,14 @@ def main():
288286
)
289287

290288
if result.success:
291-
print("\n🎉 Infrastructure creation completed successfully!")
289+
print('\n🎉 Infrastructure creation completed successfully!')
292290
sys.exit(0)
293291
else:
294-
print("\n💥 Infrastructure creation failed!")
292+
print('\n💥 Infrastructure creation failed!')
295293
sys.exit(1)
296294

297295
except Exception as e:
298-
print(f"\n💥 Error: {str(e)}")
296+
print(f'\n💥 Error: {str(e)}')
299297
sys.exit(1)
300298

301299

0 commit comments

Comments
 (0)