0
# Private Networking
1
2
Private endpoint connections for secure registry access through Azure Virtual Networks, supporting private connectivity and network isolation. This enables registry access over private IP addresses within your virtual network, ensuring traffic doesn't traverse the public internet.
3
4
## Capabilities
5
6
### Private Endpoint Connection Management
7
8
Create, manage, and monitor private endpoint connections that provide secure, private access to the container registry from within Azure virtual networks.
9
10
```python { .api }
11
def begin_create_or_update(resource_group_name: str, registry_name: str, private_endpoint_connection_name: str, private_endpoint_connection: PrivateEndpointConnection, **kwargs) -> LROPoller[PrivateEndpointConnection]:
12
"""
13
Create or update a private endpoint connection for a container registry.
14
15
Parameters:
16
- resource_group_name: str - Name of the resource group
17
- registry_name: str - Name of the registry
18
- private_endpoint_connection_name: str - Name of the private endpoint connection
19
- private_endpoint_connection: PrivateEndpointConnection - Connection configuration
20
21
Returns:
22
LROPoller[PrivateEndpointConnection] - Long-running operation poller for the connection
23
"""
24
25
def begin_delete(resource_group_name: str, registry_name: str, private_endpoint_connection_name: str, **kwargs) -> LROPoller[None]:
26
"""
27
Delete a private endpoint connection from a container registry.
28
29
Parameters:
30
- resource_group_name: str - Name of the resource group
31
- registry_name: str - Name of the registry
32
- private_endpoint_connection_name: str - Name of the connection to delete
33
34
Returns:
35
LROPoller[None] - Long-running operation poller
36
"""
37
38
def get(resource_group_name: str, registry_name: str, private_endpoint_connection_name: str, **kwargs) -> PrivateEndpointConnection:
39
"""
40
Get properties of a private endpoint connection.
41
42
Parameters:
43
- resource_group_name: str - Name of the resource group
44
- registry_name: str - Name of the registry
45
- private_endpoint_connection_name: str - Name of the private endpoint connection
46
47
Returns:
48
PrivateEndpointConnection - Private endpoint connection with complete configuration
49
"""
50
51
def list(resource_group_name: str, registry_name: str, **kwargs) -> ItemPaged[PrivateEndpointConnection]:
52
"""
53
List all private endpoint connections for a container registry.
54
55
Parameters:
56
- resource_group_name: str - Name of the resource group
57
- registry_name: str - Name of the registry
58
59
Returns:
60
ItemPaged[PrivateEndpointConnection] - Paginated list of all private endpoint connections
61
"""
62
```
63
64
## Core Model Types
65
66
### PrivateEndpointConnection
67
68
```python { .api }
69
class PrivateEndpointConnection:
70
"""
71
An object that represents a private endpoint connection for a container registry.
72
73
Attributes:
74
- id: str - Resource ID
75
- name: str - Resource name
76
- type: str - Resource type
77
- private_endpoint: PrivateEndpoint - Private endpoint details
78
- private_link_service_connection_state: PrivateLinkServiceConnectionState - Connection state
79
- provisioning_state: ProvisioningState - Current provisioning state
80
"""
81
```
82
83
### PrivateEndpoint
84
85
```python { .api }
86
class PrivateEndpoint:
87
"""
88
Private endpoint details.
89
90
Attributes:
91
- id: str - Resource ID of the private endpoint
92
"""
93
```
94
95
### PrivateLinkServiceConnectionState
96
97
```python { .api }
98
class PrivateLinkServiceConnectionState:
99
"""
100
Connection state for private link service.
101
102
Attributes:
103
- status: ConnectionStatus - Connection status (Approved, Pending, Rejected, Disconnected)
104
- description: str - Description of the connection state
105
- actions_required: ActionsRequired - Actions required to resolve connection issues
106
"""
107
```
108
109
### PrivateLinkResource
110
111
```python { .api }
112
class PrivateLinkResource:
113
"""
114
A private link resource for a container registry.
115
116
Attributes:
117
- id: str - Resource ID
118
- name: str - Resource name
119
- type: str - Resource type
120
- group_id: str - Group ID of the private link resource
121
- required_members: List[str] - Required members for the private link resource
122
- required_zone_names: List[str] - Required DNS zone names
123
"""
124
```
125
126
### PrivateLinkResourceListResult
127
128
```python { .api }
129
class PrivateLinkResourceListResult:
130
"""
131
Result of listing private link resources.
132
133
Attributes:
134
- value: List[PrivateLinkResource] - List of private link resources
135
"""
136
```
137
138
## Enums
139
140
### ConnectionStatus
141
142
```python { .api }
143
class ConnectionStatus(str, Enum):
144
"""Private endpoint connection status."""
145
APPROVED = "Approved"
146
PENDING = "Pending"
147
REJECTED = "Rejected"
148
DISCONNECTED = "Disconnected"
149
```
150
151
### ActionsRequired
152
153
```python { .api }
154
class ActionsRequired(str, Enum):
155
"""Actions required for private endpoint connection."""
156
NONE = "None"
157
RECREATE = "Recreate"
158
```
159
160
### ProvisioningState
161
162
```python { .api }
163
class ProvisioningState(str, Enum):
164
"""Provisioning state of a resource."""
165
CREATING = "Creating"
166
UPDATING = "Updating"
167
DELETING = "Deleting"
168
SUCCEEDED = "Succeeded"
169
FAILED = "Failed"
170
CANCELED = "Canceled"
171
```
172
173
## Usage Examples
174
175
### Create Private Endpoint Connection
176
177
```python
178
from azure.mgmt.containerregistry import ContainerRegistryManagementClient
179
from azure.mgmt.containerregistry.models import (
180
PrivateEndpointConnection, PrivateEndpoint, PrivateLinkServiceConnectionState,
181
ConnectionStatus, ActionsRequired
182
)
183
from azure.identity import DefaultAzureCredential
184
185
client = ContainerRegistryManagementClient(
186
DefaultAzureCredential(),
187
"subscription-id"
188
)
189
190
# Create or approve a private endpoint connection
191
private_endpoint_connection = PrivateEndpointConnection(
192
private_endpoint=PrivateEndpoint(
193
id="/subscriptions/subscription-id/resourceGroups/my-rg/providers/Microsoft.Network/privateEndpoints/my-private-endpoint"
194
),
195
private_link_service_connection_state=PrivateLinkServiceConnectionState(
196
status=ConnectionStatus.APPROVED,
197
description="Connection approved for secure access",
198
actions_required=ActionsRequired.NONE
199
)
200
)
201
202
# Create the connection
203
connection_poller = client.private_endpoint_connections.begin_create_or_update(
204
"my-resource-group",
205
"my-registry",
206
"my-private-endpoint-connection",
207
private_endpoint_connection
208
)
209
210
connection = connection_poller.result()
211
print(f"Created private endpoint connection: {connection.name}")
212
print(f"Status: {connection.private_link_service_connection_state.status}")
213
```
214
215
### List and Monitor Private Endpoint Connections
216
217
```python
218
# List all private endpoint connections
219
connections = client.private_endpoint_connections.list(
220
"my-resource-group",
221
"my-registry"
222
)
223
224
print("Private Endpoint Connections:")
225
print("-" * 50)
226
for connection in connections:
227
print(f"Connection: {connection.name}")
228
print(f" Status: {connection.private_link_service_connection_state.status}")
229
print(f" Provisioning State: {connection.provisioning_state}")
230
print(f" Private Endpoint ID: {connection.private_endpoint.id}")
231
print(f" Description: {connection.private_link_service_connection_state.description}")
232
if connection.private_link_service_connection_state.actions_required != ActionsRequired.NONE:
233
print(f" Actions Required: {connection.private_link_service_connection_state.actions_required}")
234
print()
235
```
236
237
### Approve Pending Private Endpoint Connection
238
239
```python
240
# Get a specific connection that might be pending
241
pending_connection = client.private_endpoint_connections.get(
242
"my-resource-group",
243
"my-registry",
244
"pending-connection"
245
)
246
247
if pending_connection.private_link_service_connection_state.status == ConnectionStatus.PENDING:
248
# Approve the connection
249
approved_connection = PrivateEndpointConnection(
250
private_endpoint=pending_connection.private_endpoint,
251
private_link_service_connection_state=PrivateLinkServiceConnectionState(
252
status=ConnectionStatus.APPROVED,
253
description="Connection approved by administrator",
254
actions_required=ActionsRequired.NONE
255
)
256
)
257
258
approval_poller = client.private_endpoint_connections.begin_create_or_update(
259
"my-resource-group",
260
"my-registry",
261
"pending-connection",
262
approved_connection
263
)
264
265
approved = approval_poller.result()
266
print(f"Approved connection: {approved.name}")
267
print(f"New status: {approved.private_link_service_connection_state.status}")
268
```
269
270
### Reject Private Endpoint Connection
271
272
```python
273
# Reject a private endpoint connection
274
rejected_connection = PrivateEndpointConnection(
275
private_endpoint=PrivateEndpoint(
276
id="/subscriptions/subscription-id/resourceGroups/untrusted-rg/providers/Microsoft.Network/privateEndpoints/untrusted-endpoint"
277
),
278
private_link_service_connection_state=PrivateLinkServiceConnectionState(
279
status=ConnectionStatus.REJECTED,
280
description="Connection rejected due to security policy",
281
actions_required=ActionsRequired.NONE
282
)
283
)
284
285
rejection_poller = client.private_endpoint_connections.begin_create_or_update(
286
"my-resource-group",
287
"my-registry",
288
"untrusted-connection",
289
rejected_connection
290
)
291
292
rejected = rejection_poller.result()
293
print(f"Rejected connection: {rejected.name}")
294
```
295
296
### Configure Registry for Private Access Only
297
298
```python
299
from azure.mgmt.containerregistry.models import (
300
RegistryUpdateParameters, PublicNetworkAccess, NetworkRuleSet, DefaultAction
301
)
302
303
# Update registry to disable public access and require private endpoints
304
registry_update_params = RegistryUpdateParameters(
305
public_network_access=PublicNetworkAccess.DISABLED,
306
network_rule_set=NetworkRuleSet(
307
default_action=DefaultAction.DENY,
308
ip_rules=[] # No IP rules since we're using private endpoints only
309
)
310
)
311
312
updated_registry = client.registries.begin_update(
313
"my-resource-group",
314
"my-registry",
315
registry_update_params
316
).result()
317
318
print(f"Updated registry for private access only")
319
print(f"Public network access: {updated_registry.public_network_access}")
320
```
321
322
### Get Private Link Resources
323
324
```python
325
# List available private link resources for the registry
326
private_link_resources = client.registries.list_private_link_resources(
327
"my-resource-group",
328
"my-registry"
329
)
330
331
print("Available Private Link Resources:")
332
print("-" * 40)
333
for resource in private_link_resources.value:
334
print(f"Resource: {resource.name}")
335
print(f" Group ID: {resource.group_id}")
336
print(f" Required Members: {resource.required_members}")
337
print(f" Required Zone Names: {resource.required_zone_names}")
338
print()
339
340
# Get specific private link resource
341
if private_link_resources.value:
342
specific_resource = client.registries.get_private_link_resource(
343
"my-resource-group",
344
"my-registry",
345
private_link_resources.value[0].group_id
346
)
347
print(f"Specific resource details: {specific_resource.name}")
348
```
349
350
### Complete Private Networking Setup
351
352
```python
353
# Complete setup for private networking including DNS configuration
354
import json
355
356
def setup_private_networking(client, resource_group, registry_name, vnet_config):
357
"""
358
Complete private networking setup for a container registry.
359
"""
360
361
# Step 1: Configure registry for private access
362
print("Configuring registry for private access...")
363
registry_params = RegistryUpdateParameters(
364
public_network_access=PublicNetworkAccess.DISABLED,
365
network_rule_set=NetworkRuleSet(default_action=DefaultAction.DENY)
366
)
367
368
client.registries.begin_update(
369
resource_group,
370
registry_name,
371
registry_params
372
).result()
373
374
# Step 2: Get private link resources info for DNS setup
375
print("Getting private link resource information...")
376
private_link_resources = client.registries.list_private_link_resources(
377
resource_group,
378
registry_name
379
)
380
381
dns_config = {}
382
for resource in private_link_resources.value:
383
dns_config[resource.group_id] = {
384
"required_zone_names": resource.required_zone_names,
385
"required_members": resource.required_members
386
}
387
388
# Step 3: List existing private endpoint connections
389
print("Checking existing private endpoint connections...")
390
connections = list(client.private_endpoint_connections.list(
391
resource_group,
392
registry_name
393
))
394
395
# Step 4: Auto-approve connections from trusted subnets
396
trusted_subnets = vnet_config.get("trusted_subnets", [])
397
398
for connection in connections:
399
if connection.private_link_service_connection_state.status == ConnectionStatus.PENDING:
400
# Check if private endpoint is from trusted subnet
401
pe_id = connection.private_endpoint.id
402
should_approve = any(subnet in pe_id for subnet in trusted_subnets)
403
404
if should_approve:
405
approved_connection = PrivateEndpointConnection(
406
private_endpoint=connection.private_endpoint,
407
private_link_service_connection_state=PrivateLinkServiceConnectionState(
408
status=ConnectionStatus.APPROVED,
409
description="Auto-approved from trusted subnet",
410
actions_required=ActionsRequired.NONE
411
)
412
)
413
414
client.private_endpoint_connections.begin_create_or_update(
415
resource_group,
416
registry_name,
417
connection.name,
418
approved_connection
419
).result()
420
421
print(f"Auto-approved connection: {connection.name}")
422
423
return {
424
"registry_status": "private_access_configured",
425
"dns_configuration": dns_config,
426
"approved_connections": len([c for c in connections if c.private_link_service_connection_state.status == ConnectionStatus.APPROVED])
427
}
428
429
# Example usage
430
vnet_configuration = {
431
"trusted_subnets": [
432
"/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/trusted-subnet",
433
"/subscriptions/sub-id/resourceGroups/rg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/app-subnet"
434
]
435
}
436
437
result = setup_private_networking(
438
client,
439
"my-resource-group",
440
"my-registry",
441
vnet_configuration
442
)
443
444
print("Private networking setup completed:")
445
print(json.dumps(result, indent=2))
446
```
447
448
### Monitor Private Endpoint Health
449
450
```python
451
def monitor_private_endpoints(client, resource_group, registry_name):
452
"""
453
Monitor the health and status of private endpoint connections.
454
"""
455
connections = list(client.private_endpoint_connections.list(
456
resource_group,
457
registry_name
458
))
459
460
health_report = {
461
"total_connections": len(connections),
462
"approved": 0,
463
"pending": 0,
464
"rejected": 0,
465
"disconnected": 0,
466
"failed": 0,
467
"needs_attention": []
468
}
469
470
for connection in connections:
471
status = connection.private_link_service_connection_state.status
472
473
if status == ConnectionStatus.APPROVED:
474
health_report["approved"] += 1
475
elif status == ConnectionStatus.PENDING:
476
health_report["pending"] += 1
477
health_report["needs_attention"].append({
478
"connection": connection.name,
479
"issue": "Pending approval",
480
"action": "Review and approve/reject"
481
})
482
elif status == ConnectionStatus.REJECTED:
483
health_report["rejected"] += 1
484
elif status == ConnectionStatus.DISCONNECTED:
485
health_report["disconnected"] += 1
486
health_report["needs_attention"].append({
487
"connection": connection.name,
488
"issue": "Disconnected",
489
"action": "Check private endpoint configuration"
490
})
491
492
# Check provisioning state
493
if connection.provisioning_state == ProvisioningState.FAILED:
494
health_report["failed"] += 1
495
health_report["needs_attention"].append({
496
"connection": connection.name,
497
"issue": f"Provisioning failed",
498
"action": "Review error details and retry"
499
})
500
501
# Check if actions are required
502
if connection.private_link_service_connection_state.actions_required != ActionsRequired.NONE:
503
health_report["needs_attention"].append({
504
"connection": connection.name,
505
"issue": f"Actions required: {connection.private_link_service_connection_state.actions_required}",
506
"action": "Take required action"
507
})
508
509
return health_report
510
511
# Monitor private endpoint health
512
health_status = monitor_private_endpoints(
513
client,
514
"my-resource-group",
515
"my-registry"
516
)
517
518
print("Private Endpoint Health Report:")
519
print("=" * 40)
520
print(f"Total Connections: {health_status['total_connections']}")
521
print(f"Approved: {health_status['approved']}")
522
print(f"Pending: {health_status['pending']}")
523
print(f"Rejected: {health_status['rejected']}")
524
print(f"Disconnected: {health_status['disconnected']}")
525
print(f"Failed: {health_status['failed']}")
526
527
if health_status["needs_attention"]:
528
print("\nIssues Requiring Attention:")
529
print("-" * 30)
530
for issue in health_status["needs_attention"]:
531
print(f"Connection: {issue['connection']}")
532
print(f" Issue: {issue['issue']}")
533
print(f" Action: {issue['action']}")
534
print()
535
```