or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

access-control.mdcache-and-credentials.mdconnected-registries.mdindex.mdprivate-networking.mdregistry-management.mdreplication-management.mdwebhook-management.md

private-networking.mddocs/

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

```