Skip to content

Private Endpoints

Private Endpoint Connections allow users to manage private network access to a resource. Resource providers that support private endpoint connections must declare a private endpoint connection resource type in their provider namespace and use the standard PrivateEndpoints interface to expose operations.

Defining a Private Endpoint Connection Resource

Section titled “Defining a Private Endpoint Connection Resource”

To define a private endpoint connection resource, create a model in your provider namespace that extends PrivateEndpointConnectionResource:

model PrivateEndpointConnection is PrivateEndpointConnectionResource;

Create an alias for your private endpoint operations using the PrivateEndpoints interface template:

alias PrivateEndpointOps = PrivateEndpoints<PrivateEndpointConnection>;

Adding Private Endpoint Operations to Your Resource Interface

Section titled “Adding Private Endpoint Operations to Your Resource Interface”

Add private endpoint operations to your resource interface using the operations alias:

@armResourceOperations
interface Employees {
// ... other resource operations ...
getConnection is PrivateEndpointOps.Read<Employee>;
createOrUpdateConnection is PrivateEndpointOps.CreateOrUpdateAsync<Employee>;
updateConnection is PrivateEndpointOps.CustomPatchAsync<Employee>;
deleteConnection is PrivateEndpointOps.DeleteAsync<Employee>;
listConnections is PrivateEndpointOps.ListByParent<Employee>;
}

The PrivateEndpoints interface provides the following operations:

OperationDescriptionTypeSpec Representation
ReadGet a private endpoint connectionget is Ops.Read<ParentResource>;
CreateOrUpdateAsyncCreate or update a connection (async)create is Ops.CreateOrUpdateAsync<ParentResource>;
CreateOrReplaceSyncCreate or replace a connection (sync)create is Ops.CreateOrReplaceSync<ParentResource>;
CreateOrReplaceAsyncCreate or replace a connection (async)create is Ops.CreateOrReplaceAsync<ParentResource>;
CustomPatchAsyncUpdate a connection with custom PATCH payload (async)update is Ops.CustomPatchAsync<ParentResource>;
CustomPatchSyncUpdate a connection with custom PATCH payload (sync)update is Ops.CustomPatchSync<ParentResource>;
DeleteAsyncDelete a connection (async)delete is Ops.DeleteAsync<ParentResource>;
DeleteSyncDelete a connection (sync)delete is Ops.DeleteSync<ParentResource>;
ListByParentList connections for a parent resourcelist is Ops.ListByParent<ParentResource>;

The following example shows a complete service with private endpoint connection support:

Sample specification adding private endpoints to a resource.

Try it
main.tsp
import "@typespec/rest";
import "@typespec/versioning";
import "@azure-tools/typespec-azure-core";
import "@azure-tools/typespec-azure-resource-manager";
using Rest;
using Versioning;
using Azure.Core;
using Azure.ResourceManager;
/** Contoso Resource Provider management API. */
@armProviderNamespace
@service(#{ title: "ContosoProviderHubClient" })
@versioned(Versions)
namespace Microsoft.ContosoProviderHub;
/** Contoso API versions */
enum Versions {
/** 2021-10-01-preview version */
@armCommonTypesVersion(Azure.ResourceManager.CommonTypes.Versions.v5)
@previewVersion
`2021-10-01-preview`,
}
// For more information about the proxy vs tracked,
// see https://armwiki.azurewebsites.net/rp_onboarding/tracked_vs_proxy_resources.html?q=proxy%20resource
/** A ContosoProviderHub resource */
model Employee is TrackedResource<EmployeeProperties> {
...ResourceNameParameter<Employee>;
}
/** Employee properties */
model EmployeeProperties {
/** Age of employee */
age?: int32;
/** City of employee */
city?: string;
/** Profile of employee */
@encode("base64url")
profile?: bytes;
/** The status of the last operation. */
@visibility(Lifecycle.Read)
provisioningState?: ProvisioningState;
}
/** The provisioning state of a resource. */
@lroStatus
union ProvisioningState {
ResourceProvisioningState,
/** The resource is being provisioned */
Provisioning: "Provisioning",
/** The resource is updating */
Updating: "Updating",
/** The resource is being deleted */
Deleting: "Deleting",
/** The resource create request has been accepted */
Accepted: "Accepted",
string,
}
interface Operations extends Azure.ResourceManager.Operations {}
model PrivateEndpointConnection is PrivateEndpointConnectionResource;
alias PrivateEndpointOperations = PrivateEndpoints<PrivateEndpointConnection>;
@armResourceOperations
interface Employees {
get is ArmResourceRead<Employee>;
createOrUpdate is ArmResourceCreateOrReplaceAsync<Employee>;
update is ArmCustomPatchSync<
Employee,
Azure.ResourceManager.Foundations.ResourceUpdateModel<Employee, EmployeeProperties>
>;
delete is ArmResourceDeleteSync<Employee>;
listByResourceGroup is ArmResourceListByParent<Employee>;
listBySubscription is ArmListBySubscription<Employee>;
/** A sample resource action that move employee to different location */
move is ArmResourceActionSync<Employee, MoveRequest, MoveResponse>;
/** A sample HEAD operation to check resource existence */
checkExistence is ArmResourceCheckExistence<Employee>;
getPrivateEndpointConnection is PrivateEndpointOperations.Read<Employee>;
createOrUpdatePrivateEndpointConnection is PrivateEndpointOperations.CreateOrUpdateAsync<Employee>;
updatePrivateEndpointConnection is PrivateEndpointOperations.CustomPatchAsync<Employee>;
deletePrivateEndpointConnection is PrivateEndpointOperations.DeleteAsync<Employee>;
listPrivateEndpointConnections is PrivateEndpointOperations.ListByParent<Employee>;
}
/** Employee move request */
model MoveRequest {
/** The moving from location */
from: string;
/** The moving to location */
to: string;
}
/** Employee move response */
model MoveResponse {
/** The status of the move */
movingStatus: string;
}
@armResourceOperations
interface Dependents {
get is ArmResourceRead<Dependent>;
createOrUpdate is ArmResourceCreateOrReplaceAsync<Dependent>;
update is ArmCustomPatchSync<
Dependent,
Azure.ResourceManager.Foundations.ResourceUpdateModel<Dependent, DependentProperties>
>;
delete is ArmResourceDeleteSync<Dependent>;
list is ArmResourceListByParent<Dependent>;
getPrivateEndpointConnection is PrivateEndpointOperations.Read<Dependent>;
createOrUpdatePrivateEndpointConnection is PrivateEndpointOperations.CreateOrUpdateAsync<Dependent>;
updatePrivateEndpointConnection is PrivateEndpointOperations.CustomPatchAsync<Dependent>;
deletePrivateEndpointConnection is PrivateEndpointOperations.DeleteAsync<Dependent>;
listPrivateEndpointConnections is PrivateEndpointOperations.ListByParent<Dependent>;
}
/** An employee dependent */
@parentResource(Employee)
model Dependent is ProxyResource<DependentProperties> {
...ResourceNameParameter<Dependent>;
}
/** Dependent properties */
model DependentProperties {
/** Age of dependent */
age: int32;
/** Gender of dependent */
gender: string;
/** The status of the last operation. */
@visibility(Lifecycle.Read)
provisioningState?: ProvisioningState;
}

Using Private Endpoints with Child Resources

Section titled “Using Private Endpoints with Child Resources”

Private endpoint operations can also be used with child resources. You can reuse the same operations alias across multiple resource interfaces:

@parentResource(Employee)
model Dependent is ProxyResource<DependentProperties> {
...ResourceNameParameter<Dependent>;
}
@armResourceOperations
interface Dependents {
get is ArmResourceRead<Dependent>;
createOrUpdate is ArmResourceCreateOrReplaceAsync<Dependent>;
delete is ArmResourceDeleteSync<Dependent>;
list is ArmResourceListByParent<Dependent>;
// Reuse the same private endpoint operations alias
getPrivateEndpointConnection is PrivateEndpointOps.Read<Dependent>;
createOrUpdatePrivateEndpointConnection is PrivateEndpointOps.CreateOrUpdateAsync<Dependent>;
deletePrivateEndpointConnection is PrivateEndpointOps.DeleteAsync<Dependent>;
listPrivateEndpointConnections is PrivateEndpointOps.ListByParent<Dependent>;
}