Adding Custom Resources to Azure REST API

This article will go through the requirements and best practices for creating Azure Custom Resource Provider endpoints that implements custom resources. If you are unfamiliar with Azure Custom Resource Providers, see the overview on custom resource providers.

How to define a resource endpoint

An endpoint is a URL that points to a service, which implements the underlying contract between it and Azure. The endpoint is defined in the custom resource provider and can be any publicly accessible URL. The sample below has an resourceType called myCustomResource implemented by endpointURL.

Sample ResourceProvider:

{
  "properties": {
    "resourceTypes": [
      {
        "name": "myCustomResource",
        "routingType": "Proxy, Cache",
        "endpoint": "https://{endpointURL}/"
      }
    ]
  },
  "location": "eastus",
  "type": "Microsoft.CustomProviders/resourceProviders",
  "id": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CustomProviders/resourceProviders/{resourceProviderName}",
  "name": "{resourceProviderName}"
}

Building a resource endpoint

An endpoint that implements an resourceType must handle the request and response for the new API in Azure. When a custom resource provider with an resourceType is created, it will generate a new set of APIs in Azure. In this case, the resourceType will generate a new Azure resource API for PUT, GET, and DELETE to perform CRUD on a single resource as well as GET to retrieve all existing resources:

Manipulate Single Resource (PUT, GET, and DELETE):

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CustomProviders/resourceProviders/{resourceProviderName}/myCustomResource/{myCustomResourceName}

Retrieve All Resources (GET):

/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CustomProviders/resourceProviders/{resourceProviderName}/myCustomResource

For custom resources, custom resource providers offer two types of routingTypes: "Proxy" and "Proxy, Cache".

proxy routing type

The "Proxy" routingType proxies all request methods to the endpoint specified in the custom resource provider. When to use "Proxy":

  • Full control over the response is needed.
  • Integrating systems with existing resources.

To learn more about "Proxy" resources, see the custom resource proxy reference

proxy cache routing type

The "Proxy, Cache" routingType proxies only PUT and DELETE request methods to the endpoint specified in the custom resource provider. The custom resource provider will automatically return GET requests based on what it has stored in its cache. If a custom resource is marked with cache, the custom resource provider will also add / overwrite fields in the response to make the APIs Azure compliant. When to use "Proxy, Cache":

  • Creating a new system that has no existing resources.
  • Work with existing Azure ecosystem.

To learn more about "Proxy, Cache" resources, see the custom resource cache reference

Creating a custom resource

There are two main ways of creating a custom resource off of a custom resource provider:

  • Azure CLI
  • Azure Resource Manager Templates

Azure CLI

Create a custom resource:

az resource create --is-full-object \
                   --id /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CustomProviders/resourceProviders/{resourceProviderName}/{resourceTypeName}/{customResourceName} \
                   --properties \
                    '{
                        "location": "eastus",
                        "properties": {
                            "myProperty1": "myPropertyValue1",
                            "myProperty2": {
                                "myProperty3": "myPropertyValue3"
                            }
                        }
                    }'
Parameter Required Description
is-full-object yes Indicates that the properties object includes other options such as location, tags, sku, and/or plan.
id yes The resource ID of the custom resource. This should exist off of the ResourceProvider
properties yes The request body that will be sent to the endpoint.

Delete an Azure Custom Resource:

az resource delete --id /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CustomProviders/resourceProviders/{resourceProviderName}/{resourceTypeName}/{customResourceName}
Parameter Required Description
id yes The resource ID of the custom resource. This should exist off of the ResourceProvider.

Retrieve an Azure Custom Resource:

az resource show --id /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CustomProviders/resourceProviders/{resourceProviderName}/{resourceTypeName}/{customResourceName}
Parameter Required Description
id yes The resource ID of the custom resource. This should exist off of the ResourceProvider

Azure Resource Manager Template

Note

Resources require that the response contain an appropriate id, name, and type from the endpoint.

Azure Resource Manager Templates require that id, name, and type are returned correctly from the downstream endpoint. A returned resource response should be in the form:

Sample endpoint response:

{
  "properties": {
    "myProperty1": "myPropertyValue1",
    "myProperty2": {
        "myProperty3": "myPropertyValue3"
    }
  },
  "id": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CustomProviders/resourceProviders/{customResourceName}",
  "name": "{customResourceName}",
  "type": "Microsoft.CustomProviders/resourceProviders/{resourceTypeName}"
}

Sample Azure Resource Manager Template:

{
    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "resources": [
        {
            "type": "Microsoft.CustomProviders/resourceProviders/{resourceTypeName}",
            "name": "{resourceProviderName}/{customResourceName}",
            "apiVersion": "2018-09-01-preview",
            "location": "eastus",
            "properties": {
                "myProperty1": "myPropertyValue1",
                "myProperty2": {
                    "myProperty3": "myPropertyValue3"
                }
            }
        }
    ]
}
Parameter Required Description
resourceTypeName yes The name of the resourceType defined in the custom resource provider.
resourceProviderName yes The custom resource provider instance name.
customResourceName yes The custom resource name.

Next steps