0
# Private Networking Operations
1
2
The Azure App Configuration Management Client provides comprehensive support for private networking through private endpoints and private link resources. This enables secure, private connectivity to your App Configuration stores from Azure virtual networks.
3
4
## Operations Classes
5
6
### PrivateEndpointConnectionsOperations
7
8
```python { .api }
9
class PrivateEndpointConnectionsOperations:
10
"""
11
Operations for managing private endpoint connections to App Configuration stores.
12
13
Private endpoint connections allow secure access to App Configuration stores from
14
within Azure virtual networks, keeping traffic on the Microsoft backbone network.
15
"""
16
```
17
18
### PrivateLinkResourcesOperations
19
20
```python { .api }
21
class PrivateLinkResourcesOperations:
22
"""
23
Operations for managing private link resources associated with App Configuration stores.
24
25
Private link resources define the target sub-resources that can be connected to
26
via private endpoints, such as 'configurationStores' for App Configuration.
27
"""
28
```
29
30
## Private Endpoint Connection Management
31
32
### List Private Endpoint Connections
33
34
```python { .api }
35
def list_by_configuration_store(
36
self,
37
resource_group_name: str,
38
config_store_name: str,
39
**kwargs: Any
40
) -> ItemPaged[PrivateEndpointConnection]:
41
"""
42
Lists all private endpoint connections for an App Configuration store.
43
44
Args:
45
resource_group_name: The name of the resource group containing the store.
46
config_store_name: The name of the configuration store.
47
**kwargs: Additional keyword arguments for the request.
48
49
Returns:
50
ItemPaged[PrivateEndpointConnection]: A collection of private endpoint connections.
51
52
Example:
53
>>> connections = client.private_endpoint_connections.list_by_configuration_store(
54
... "my-rg", "my-store"
55
... )
56
>>> for conn in connections:
57
... print(f"Connection: {conn.name}")
58
... print(f"Status: {conn.private_link_service_connection_state.status}")
59
... print(f"Private Endpoint: {conn.private_endpoint.id}")
60
"""
61
```
62
63
### Get Private Endpoint Connection
64
65
```python { .api }
66
def get(
67
self,
68
resource_group_name: str,
69
config_store_name: str,
70
private_endpoint_connection_name: str,
71
**kwargs: Any
72
) -> PrivateEndpointConnection:
73
"""
74
Gets the details of a specific private endpoint connection.
75
76
Args:
77
resource_group_name: The name of the resource group containing the store.
78
config_store_name: The name of the configuration store.
79
private_endpoint_connection_name: The name of the private endpoint connection.
80
**kwargs: Additional keyword arguments for the request.
81
82
Returns:
83
PrivateEndpointConnection: The private endpoint connection details.
84
85
Example:
86
>>> connection = client.private_endpoint_connections.get(
87
... "my-rg", "my-store", "my-private-endpoint-connection"
88
... )
89
>>> print(f"Connection state: {connection.private_link_service_connection_state.status}")
90
>>> print(f"Description: {connection.private_link_service_connection_state.description}")
91
"""
92
```
93
94
### Create or Update Private Endpoint Connection
95
96
```python { .api }
97
def begin_create_or_update(
98
self,
99
resource_group_name: str,
100
config_store_name: str,
101
private_endpoint_connection_name: str,
102
private_endpoint_connection: PrivateEndpointConnection,
103
**kwargs: Any
104
) -> LROPoller[PrivateEndpointConnection]:
105
"""
106
Creates or updates a private endpoint connection for an App Configuration store.
107
108
Args:
109
resource_group_name: The name of the resource group containing the store.
110
config_store_name: The name of the configuration store.
111
private_endpoint_connection_name: The name for the private endpoint connection.
112
private_endpoint_connection: The private endpoint connection parameters.
113
**kwargs: Additional keyword arguments for the request.
114
115
Returns:
116
LROPoller[PrivateEndpointConnection]: A poller for the long-running operation.
117
118
Example:
119
>>> from azure.mgmt.appconfiguration.models import (
120
... PrivateEndpointConnection,
121
... PrivateLinkServiceConnectionState,
122
... ConnectionStatus
123
... )
124
>>> connection_state = PrivateLinkServiceConnectionState(
125
... status=ConnectionStatus.APPROVED,
126
... description="Approved by administrator"
127
... )
128
>>> connection = PrivateEndpointConnection(
129
... private_link_service_connection_state=connection_state
130
... )
131
>>> poller = client.private_endpoint_connections.begin_create_or_update(
132
... "my-rg", "my-store", "my-connection", connection
133
... )
134
>>> result = poller.result()
135
"""
136
```
137
138
### Delete Private Endpoint Connection
139
140
```python { .api }
141
def begin_delete(
142
self,
143
resource_group_name: str,
144
config_store_name: str,
145
private_endpoint_connection_name: str,
146
**kwargs: Any
147
) -> LROPoller[None]:
148
"""
149
Deletes a private endpoint connection from an App Configuration store.
150
151
Args:
152
resource_group_name: The name of the resource group containing the store.
153
config_store_name: The name of the configuration store.
154
private_endpoint_connection_name: The name of the private endpoint connection to delete.
155
**kwargs: Additional keyword arguments for the request.
156
157
Returns:
158
LROPoller[None]: A poller for the long-running delete operation.
159
160
Example:
161
>>> delete_poller = client.private_endpoint_connections.begin_delete(
162
... "my-rg", "my-store", "my-connection"
163
... )
164
>>> delete_poller.wait() # Wait for deletion to complete
165
>>> print("Private endpoint connection deleted")
166
"""
167
```
168
169
## Private Link Resource Management
170
171
### List Private Link Resources
172
173
```python { .api }
174
def list_by_configuration_store(
175
self,
176
resource_group_name: str,
177
config_store_name: str,
178
**kwargs: Any
179
) -> ItemPaged[PrivateLinkResource]:
180
"""
181
Lists the private link resources supported by an App Configuration store.
182
183
Args:
184
resource_group_name: The name of the resource group containing the store.
185
config_store_name: The name of the configuration store.
186
**kwargs: Additional keyword arguments for the request.
187
188
Returns:
189
ItemPaged[PrivateLinkResource]: A collection of private link resources.
190
191
Example:
192
>>> resources = client.private_link_resources.list_by_configuration_store(
193
... "my-rg", "my-store"
194
... )
195
>>> for resource in resources:
196
... print(f"Resource: {resource.group_id}")
197
... print(f"Required members: {resource.required_members}")
198
... print(f"Required zone names: {resource.required_zone_names}")
199
"""
200
```
201
202
### Get Private Link Resource
203
204
```python { .api }
205
def get(
206
self,
207
resource_group_name: str,
208
config_store_name: str,
209
group_name: str,
210
**kwargs: Any
211
) -> PrivateLinkResource:
212
"""
213
Gets the details of a private link resource for an App Configuration store.
214
215
Args:
216
resource_group_name: The name of the resource group containing the store.
217
config_store_name: The name of the configuration store.
218
group_name: The name of the private link resource group.
219
**kwargs: Additional keyword arguments for the request.
220
221
Returns:
222
PrivateLinkResource: The private link resource details.
223
224
Example:
225
>>> resource = client.private_link_resources.get(
226
... "my-rg", "my-store", "configurationStores"
227
... )
228
>>> print(f"Group ID: {resource.group_id}")
229
>>> print(f"Required members: {resource.required_members}")
230
"""
231
```
232
233
## Model Classes
234
235
### PrivateEndpointConnection
236
237
```python { .api }
238
class PrivateEndpointConnection:
239
"""
240
Represents a private endpoint connection to an App Configuration store.
241
242
Attributes:
243
id (str): The resource ID of the connection (read-only).
244
name (str): The name of the connection (read-only).
245
type (str): The type of the connection (read-only).
246
private_endpoint (PrivateEndpoint): The private endpoint details.
247
private_link_service_connection_state (PrivateLinkServiceConnectionState):
248
The connection state information.
249
provisioning_state (str): The provisioning state (read-only).
250
"""
251
```
252
253
### PrivateEndpoint
254
255
```python { .api }
256
class PrivateEndpoint:
257
"""
258
Represents a private endpoint resource.
259
260
Attributes:
261
id (str): The resource ID of the private endpoint (read-only).
262
"""
263
```
264
265
### PrivateLinkServiceConnectionState
266
267
```python { .api }
268
class PrivateLinkServiceConnectionState:
269
"""
270
Represents the connection state of a private link service connection.
271
272
Attributes:
273
status (ConnectionStatus): The connection status.
274
description (str): Description of the connection state.
275
actions_required (ActionsRequired): Actions required for the connection.
276
"""
277
278
def __init__(
279
self,
280
*,
281
status: Optional[ConnectionStatus] = None,
282
description: Optional[str] = None,
283
actions_required: Optional[ActionsRequired] = None,
284
**kwargs: Any
285
) -> None:
286
"""
287
Initialize connection state.
288
289
Args:
290
status: The connection status (Pending, Approved, Rejected, Disconnected).
291
description: Human-readable description of the state.
292
actions_required: Actions required beyond basic workflow.
293
"""
294
```
295
296
### PrivateLinkResource
297
298
```python { .api }
299
class PrivateLinkResource:
300
"""
301
Represents a private link resource that can be connected to via private endpoint.
302
303
Attributes:
304
id (str): The resource ID (read-only).
305
name (str): The name of the resource (read-only).
306
type (str): The type of the resource (read-only).
307
group_id (str): The private link resource group ID.
308
required_members (List[str]): Required member names for the resource.
309
required_zone_names (List[str]): Required DNS zone names for the resource.
310
"""
311
```
312
313
## Connection Status Enumeration
314
315
```python { .api }
316
class ConnectionStatus:
317
"""
318
Enumeration of private endpoint connection statuses.
319
320
Values:
321
PENDING: Connection is pending approval.
322
APPROVED: Connection has been approved.
323
REJECTED: Connection has been rejected.
324
DISCONNECTED: Connection has been disconnected.
325
"""
326
PENDING = "Pending"
327
APPROVED = "Approved"
328
REJECTED = "Rejected"
329
DISCONNECTED = "Disconnected"
330
```
331
332
## Practical Usage Examples
333
334
### Setting Up Private Endpoint Connectivity
335
336
```python { .api }
337
from azure.mgmt.appconfiguration import AppConfigurationManagementClient
338
from azure.mgmt.appconfiguration.models import (
339
PrivateEndpointConnection,
340
PrivateLinkServiceConnectionState,
341
ConnectionStatus,
342
ActionsRequired
343
)
344
from azure.identity import DefaultAzureCredential
345
346
# Initialize client
347
credential = DefaultAzureCredential()
348
client = AppConfigurationManagementClient(credential, "subscription-id")
349
350
resource_group = "my-resource-group"
351
store_name = "my-config-store"
352
353
# Step 1: Check available private link resources
354
print("Checking available private link resources...")
355
link_resources = client.private_link_resources.list_by_configuration_store(
356
resource_group, store_name
357
)
358
359
for resource in link_resources:
360
print(f"Private Link Resource: {resource.group_id}")
361
print(f" Required Members: {resource.required_members}")
362
print(f" Required Zone Names: {resource.required_zone_names}")
363
print("---")
364
365
# Step 2: Get specific resource details
366
config_resource = client.private_link_resources.get(
367
resource_group, store_name, "configurationStores"
368
)
369
print(f"Configuration Stores resource members: {config_resource.required_members}")
370
```
371
372
### Managing Private Endpoint Connection Lifecycle
373
374
```python { .api }
375
def manage_private_endpoint_connection_lifecycle():
376
"""Complete lifecycle management of private endpoint connections."""
377
378
connection_name = "my-app-private-endpoint"
379
380
# Step 1: Create/Update private endpoint connection
381
print("Creating private endpoint connection...")
382
383
# Define connection state (initially pending)
384
connection_state = PrivateLinkServiceConnectionState(
385
status=ConnectionStatus.PENDING,
386
description="Requesting private endpoint connection for secure access"
387
)
388
389
# Create connection object
390
connection = PrivateEndpointConnection(
391
private_link_service_connection_state=connection_state
392
)
393
394
# Start creation operation
395
create_poller = client.private_endpoint_connections.begin_create_or_update(
396
resource_group,
397
store_name,
398
connection_name,
399
connection
400
)
401
402
# Wait for creation to complete
403
created_connection = create_poller.result()
404
print(f"Connection created: {created_connection.name}")
405
print(f"Initial status: {created_connection.private_link_service_connection_state.status}")
406
407
# Step 2: Approve the connection
408
print("Approving private endpoint connection...")
409
410
approved_state = PrivateLinkServiceConnectionState(
411
status=ConnectionStatus.APPROVED,
412
description="Connection approved by network administrator",
413
actions_required=ActionsRequired.NONE
414
)
415
416
approved_connection = PrivateEndpointConnection(
417
private_link_service_connection_state=approved_state
418
)
419
420
approve_poller = client.private_endpoint_connections.begin_create_or_update(
421
resource_group,
422
store_name,
423
connection_name,
424
approved_connection
425
)
426
427
final_connection = approve_poller.result()
428
print(f"Connection approved: {final_connection.private_link_service_connection_state.status}")
429
430
# Step 3: Monitor connection status
431
print("Monitoring connection status...")
432
433
current_connection = client.private_endpoint_connections.get(
434
resource_group, store_name, connection_name
435
)
436
437
print(f"Current Status: {current_connection.private_link_service_connection_state.status}")
438
print(f"Description: {current_connection.private_link_service_connection_state.description}")
439
print(f"Provisioning State: {current_connection.provisioning_state}")
440
441
if current_connection.private_endpoint:
442
print(f"Private Endpoint ID: {current_connection.private_endpoint.id}")
443
444
return current_connection
445
446
# Execute the lifecycle management
447
connection = manage_private_endpoint_connection_lifecycle()
448
```
449
450
### Bulk Private Endpoint Management
451
452
```python { .api }
453
def manage_multiple_private_endpoints():
454
"""Manage multiple private endpoint connections for different environments."""
455
456
environments = {
457
"development": "dev-app-private-endpoint",
458
"staging": "staging-app-private-endpoint",
459
"production": "prod-app-private-endpoint"
460
}
461
462
connections = {}
463
464
for env, connection_name in environments.items():
465
print(f"Setting up {env} private endpoint...")
466
467
# Create environment-specific connection
468
connection_state = PrivateLinkServiceConnectionState(
469
status=ConnectionStatus.APPROVED, # Pre-approve for automation
470
description=f"Private endpoint for {env} environment"
471
)
472
473
connection = PrivateEndpointConnection(
474
private_link_service_connection_state=connection_state
475
)
476
477
try:
478
create_poller = client.private_endpoint_connections.begin_create_or_update(
479
resource_group,
480
store_name,
481
connection_name,
482
connection
483
)
484
485
result = create_poller.result()
486
connections[env] = result
487
print(f"✓ {env} connection created successfully")
488
489
except Exception as e:
490
print(f"✗ Failed to create {env} connection: {e}")
491
connections[env] = None
492
493
# List all connections for verification
494
print("\nAll private endpoint connections:")
495
all_connections = client.private_endpoint_connections.list_by_configuration_store(
496
resource_group, store_name
497
)
498
499
for conn in all_connections:
500
env = next((k for k, v in environments.items() if v in conn.name), "unknown")
501
status = conn.private_link_service_connection_state.status
502
print(f" {env}: {conn.name} - {status}")
503
504
return connections
505
506
# Set up multiple environments
507
env_connections = manage_multiple_private_endpoints()
508
```
509
510
### Connection State Management
511
512
```python { .api }
513
def demonstrate_connection_state_transitions():
514
"""Show different connection state transitions."""
515
516
connection_name = "state-demo-private-endpoint"
517
518
# Helper function to update connection state
519
def update_connection_state(status, description, actions_required=None):
520
state = PrivateLinkServiceConnectionState(
521
status=status,
522
description=description,
523
actions_required=actions_required or ActionsRequired.NONE
524
)
525
526
connection = PrivateEndpointConnection(
527
private_link_service_connection_state=state
528
)
529
530
poller = client.private_endpoint_connections.begin_create_or_update(
531
resource_group, store_name, connection_name, connection
532
)
533
return poller.result()
534
535
# State 1: Pending (initial request)
536
print("1. Setting connection to Pending...")
537
pending_conn = update_connection_state(
538
ConnectionStatus.PENDING,
539
"Initial connection request submitted"
540
)
541
print(f" Status: {pending_conn.private_link_service_connection_state.status}")
542
543
# State 2: Approved (admin approval)
544
print("2. Approving connection...")
545
approved_conn = update_connection_state(
546
ConnectionStatus.APPROVED,
547
"Connection reviewed and approved by security team"
548
)
549
print(f" Status: {approved_conn.private_link_service_connection_state.status}")
550
551
# State 3: Rejected (if needed)
552
print("3. Demonstrating rejection...")
553
rejected_conn = update_connection_state(
554
ConnectionStatus.REJECTED,
555
"Connection rejected due to security policy violation",
556
ActionsRequired.RECREATE
557
)
558
print(f" Status: {rejected_conn.private_link_service_connection_state.status}")
559
print(f" Actions Required: {rejected_conn.private_link_service_connection_state.actions_required}")
560
561
# State 4: Back to Approved (after policy update)
562
print("4. Re-approving after policy update...")
563
final_conn = update_connection_state(
564
ConnectionStatus.APPROVED,
565
"Connection re-approved after security policy update"
566
)
567
print(f" Status: {final_conn.private_link_service_connection_state.status}")
568
569
return final_conn
570
571
# Demonstrate state transitions
572
final_connection = demonstrate_connection_state_transitions()
573
```
574
575
### Private Networking Audit and Reporting
576
577
```python { .api }
578
def audit_private_networking():
579
"""Audit private networking configuration for compliance."""
580
581
print("=== Private Networking Audit Report ===")
582
583
# Check private link resources
584
print("\n1. Private Link Resources:")
585
link_resources = client.private_link_resources.list_by_configuration_store(
586
resource_group, store_name
587
)
588
589
resource_count = 0
590
for resource in link_resources:
591
resource_count += 1
592
print(f" Resource: {resource.group_id}")
593
print(f" Members: {', '.join(resource.required_members)}")
594
if resource.required_zone_names:
595
print(f" DNS Zones: {', '.join(resource.required_zone_names)}")
596
597
print(f" Total Resources: {resource_count}")
598
599
# Check private endpoint connections
600
print("\n2. Private Endpoint Connections:")
601
connections = client.private_endpoint_connections.list_by_configuration_store(
602
resource_group, store_name
603
)
604
605
connection_stats = {
606
"total": 0,
607
"approved": 0,
608
"pending": 0,
609
"rejected": 0,
610
"disconnected": 0
611
}
612
613
for conn in connections:
614
connection_stats["total"] += 1
615
status = conn.private_link_service_connection_state.status.lower()
616
617
if status in connection_stats:
618
connection_stats[status] += 1
619
620
print(f" Connection: {conn.name}")
621
print(f" Status: {conn.private_link_service_connection_state.status}")
622
print(f" Description: {conn.private_link_service_connection_state.description}")
623
624
if conn.private_endpoint:
625
print(f" Private Endpoint: {conn.private_endpoint.id}")
626
627
print(" ---")
628
629
# Summary
630
print("\n3. Summary:")
631
print(f" Private Link Resources: {resource_count}")
632
print(f" Total Connections: {connection_stats['total']}")
633
print(f" Approved: {connection_stats['approved']}")
634
print(f" Pending: {connection_stats['pending']}")
635
print(f" Rejected: {connection_stats['rejected']}")
636
print(f" Disconnected: {connection_stats['disconnected']}")
637
638
# Security recommendations
639
print("\n4. Security Recommendations:")
640
if connection_stats["pending"] > 0:
641
print(f" ⚠ Review {connection_stats['pending']} pending connections")
642
643
if connection_stats["rejected"] > 0:
644
print(f" ⚠ Investigate {connection_stats['rejected']} rejected connections")
645
646
if connection_stats["total"] == 0:
647
print(" ⚠ No private endpoints configured - consider private access")
648
649
approved_ratio = connection_stats["approved"] / max(connection_stats["total"], 1)
650
if approved_ratio < 0.8:
651
print(" ⚠ Low approval ratio - review connection policies")
652
653
return connection_stats
654
655
# Run audit
656
audit_results = audit_private_networking()
657
```
658
659
### Cleanup and Maintenance
660
661
```python { .api }
662
def cleanup_private_endpoints():
663
"""Clean up unused or rejected private endpoint connections."""
664
665
print("Cleaning up private endpoint connections...")
666
667
connections = client.private_endpoint_connections.list_by_configuration_store(
668
resource_group, store_name
669
)
670
671
cleanup_candidates = []
672
673
for conn in connections:
674
status = conn.private_link_service_connection_state.status
675
676
# Mark rejected or disconnected connections for cleanup
677
if status in [ConnectionStatus.REJECTED, ConnectionStatus.DISCONNECTED]:
678
cleanup_candidates.append({
679
"name": conn.name,
680
"status": status,
681
"description": conn.private_link_service_connection_state.description
682
})
683
684
if not cleanup_candidates:
685
print("No connections require cleanup")
686
return
687
688
print(f"Found {len(cleanup_candidates)} connections for cleanup:")
689
for candidate in cleanup_candidates:
690
print(f" - {candidate['name']} ({candidate['status']})")
691
692
# Confirm cleanup
693
if len(cleanup_candidates) > 0:
694
response = input(f"Delete {len(cleanup_candidates)} connections? (y/N): ")
695
696
if response.lower() == 'y':
697
for candidate in cleanup_candidates:
698
try:
699
print(f"Deleting {candidate['name']}...")
700
delete_poller = client.private_endpoint_connections.begin_delete(
701
resource_group, store_name, candidate['name']
702
)
703
delete_poller.wait()
704
print(f"✓ Deleted {candidate['name']}")
705
706
except Exception as e:
707
print(f"✗ Failed to delete {candidate['name']}: {e}")
708
else:
709
print("Cleanup cancelled")
710
711
# Run cleanup
712
cleanup_private_endpoints()
713
```
714
715
## Asynchronous Operations
716
717
```python { .api }
718
from azure.mgmt.appconfiguration.aio import AppConfigurationManagementClient
719
from azure.identity.aio import DefaultAzureCredential
720
import asyncio
721
722
async def async_private_networking_operations():
723
"""Demonstrate asynchronous private networking operations."""
724
725
credential = DefaultAzureCredential()
726
727
async with AppConfigurationManagementClient(credential, "subscription-id") as client:
728
# Get private link resources asynchronously
729
link_resources = client.private_link_resources.list_by_configuration_store(
730
resource_group, store_name
731
)
732
733
print("Private Link Resources:")
734
async for resource in link_resources:
735
print(f" {resource.group_id}: {resource.required_members}")
736
737
# Get all private endpoint connections
738
connections = client.private_endpoint_connections.list_by_configuration_store(
739
resource_group, store_name
740
)
741
742
print("\nPrivate Endpoint Connections:")
743
async for conn in connections:
744
status = conn.private_link_service_connection_state.status
745
print(f" {conn.name}: {status}")
746
747
# Run async operations
748
asyncio.run(async_private_networking_operations())
749
```