From 7cd22e41b5cca046167212b189a7dd1b182f2384 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:42:58 +0000 Subject: [PATCH 1/3] Initial plan From 418d3930c64f21a54a7e57a15660a0d31a0d108b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 21 Feb 2026 02:47:14 +0000 Subject: [PATCH 2/3] Update extension resource documentation to use new Extension namespace templates Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com> --- .../docs/docs/howtos/ARM/resource-type.md | 132 ++++++++++++++++-- 1 file changed, 118 insertions(+), 14 deletions(-) diff --git a/website/src/content/docs/docs/howtos/ARM/resource-type.md b/website/src/content/docs/docs/howtos/ARM/resource-type.md index c88d91c994..d28da4458f 100644 --- a/website/src/content/docs/docs/howtos/ARM/resource-type.md +++ b/website/src/content/docs/docs/howtos/ARM/resource-type.md @@ -83,26 +83,130 @@ You can find samples of Tenant Resources [in the TenantResource sample](https:// ### Extension Resource -Extension resources use the `ExtensionResource` as their base resource type, where `TProperties` is the properties model for the rp-specific properties of the resource. Here is an example: +Extension resources use the `ExtensionResource` as their base resource type, where `TProperties` is the properties model for the rp-specific properties of the resource. Extension resources augment or alter the functionality of other resources, and can be scoped to specific target resource types using the templates in the `Extension` namespace. + +#### Defining the Resource Model ```typespec -model EmployeeResource is ExtensionResource { - /** The employee name, using 'Firstname Lastname' notation */ - @segment("employees") - @key("employeeName") - @visibility(Lifecycle.Read) - @path - name: string; +model Employee is ExtensionResource { + ...ResourceNameParameter; } ``` -`@doc`: provides documentation for the 'name' property of the resource. -`@segment(employees)`: provides the resource type name for this resource. -`@key(employeeName)`: provides the parameter name for the name of the resource in operations that use this resource. -`@visibility(read)`: indicates that this property is returned in the body of responses to operations over this resource, but does not appear in the body of requests. Later sections describe the [usage of property visibility](#property-visibility-and-other-constraints). -`@path`: indicates that this property corresponds to the last segment of the url path to the resource (otherwise known as the resource identity). +`ExtensionResource`: defines the resource as an extension resource with the given properties. +`...ResourceNameParameter`: spreads in the standard resource name parameter, automatically providing the `@segment`, `@key`, `@path`, and `@visibility` decorators. + +#### Defining Operations with Scope Parameters + +The `Extension` namespace provides operation templates that take a scope parameter, allowing you to define a single set of operations that can be reused across different target scopes. Define a parameterized interface for your operations: + +```typespec +interface EmplOps { + get is Extension.Read; + create is Extension.CreateOrReplaceAsync; + update is Extension.CustomPatchSync< + Scope, + Employee, + Azure.ResourceManager.Foundations.ResourceUpdateModel + >; + delete is Extension.DeleteWithoutOkAsync; + list is Extension.ListByTarget; + move is Extension.ActionSync; +} +``` + +The available operation templates include: + +| Template | Description | +| -------------------------------- | --------------------------------------------- | +| `Extension.Read` | GET operation for the resource | +| `Extension.CreateOrReplaceAsync` | Asynchronous PUT operation | +| `Extension.CreateOrUpdateAsync` | Asynchronous PUT operation (create or update) | +| `Extension.CreateOrReplaceSync` | Synchronous PUT operation | +| `Extension.CustomPatchAsync` | Asynchronous PATCH with a custom payload | +| `Extension.CustomPatchSync` | Synchronous PATCH with a custom payload | +| `Extension.DeleteWithoutOkAsync` | Asynchronous DELETE operation | +| `Extension.DeleteSync` | Synchronous DELETE operation | +| `Extension.ListByTarget` | List resources at the given target scope | +| `Extension.ActionSync` | Synchronous POST action | +| `Extension.ActionAsync` | Asynchronous POST action | +| `Extension.CheckExistence` | HEAD operation to check resource existence | + +#### Built-in Scopes + +You can instantiate the operations interface for several built-in scopes: + +```typespec +/** Operations over any scope */ +@armResourceOperations +interface Employees extends EmplOps {} + +/** Tenant-level operations */ +@armResourceOperations +interface Tenants extends EmplOps {} + +/** Subscription-level operations */ +@armResourceOperations +interface Subscriptions extends EmplOps {} + +/** Resource group-level operations */ +@armResourceOperations +interface ResourceGroups extends EmplOps {} + +/** Management group-level operations */ +@armResourceOperations +interface ManagementGroups extends EmplOps {} +``` + +| Scope | Description | +| --------------------------- | ------------------------------------- | +| `Extension.ScopeParameter` | Any scope (uses a generic scope path) | +| `Extension.Tenant` | Tenant-level scope | +| `Extension.Subscription` | Subscription-level scope | +| `Extension.ResourceGroup` | Resource group-level scope | +| `Extension.ManagementGroup` | Management group-level scope | + +#### Targeting External Resources + +If the extension resource targets a specific resource from another provider namespace, use `Extension.ExternalResource` to define the target: + +```typespec +alias VirtualMachine = Extension.ExternalResource< + "Microsoft.Compute", + "virtualMachines", + "vmName", + NamePattern = "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,80}$", + Description = "The name of the virtual machine" +>; + +@armResourceOperations +interface VirtualMachines extends EmplOps {} +``` + +For child resources of external providers, use `Extension.ExternalChildResource`: + +```typespec +alias Scaleset = Extension.ExternalResource< + "Microsoft.Compute", + "virtualMachineScaleSets", + "scaleSetName", + NamePattern = "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,80}$", + Description = "The name of the virtual machine scale set" +>; + +alias VirtualMachineScaleSetVm = Extension.ExternalChildResource< + Scaleset, + "virtualMachineScaleSetVms", + "scaleSetVmName", + NamePattern = "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,80}$", + Description = "The name of the virtual machine scale set VM" +>; + +@armResourceOperations +interface ScaleSetVms extends EmplOps {} +``` -You can find samples of Extension Resources [in the TenantResource sample](https://github.com/Azure/typespec-azure/blob/main/packages/samples/specs/resource-manager/tenantResource/main.tsp). +You can find the complete sample of Extension Resources [in the specific-extension sample](https://github.com/Azure/typespec-azure/blob/main/packages/samples/specs/resource-manager/resource-types/specific-extension/main.tsp). ### Child Resource From 5f514a14c88803d0c03c14674f9ee01e051de4ff Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 24 Feb 2026 01:28:16 +0000 Subject: [PATCH 3/3] Address PR review feedback on extension resource documentation Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com> --- .../docs/docs/howtos/ARM/resource-type.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/website/src/content/docs/docs/howtos/ARM/resource-type.md b/website/src/content/docs/docs/howtos/ARM/resource-type.md index d28da4458f..c26fc1b228 100644 --- a/website/src/content/docs/docs/howtos/ARM/resource-type.md +++ b/website/src/content/docs/docs/howtos/ARM/resource-type.md @@ -94,11 +94,11 @@ model Employee is ExtensionResource { ``` `ExtensionResource`: defines the resource as an extension resource with the given properties. -`...ResourceNameParameter`: spreads in the standard resource name parameter, automatically providing the `@segment`, `@key`, `@path`, and `@visibility` decorators. +`...ResourceNameParameter`: spreads in the standard resource name parameter, which defines the resource type name, the name of the resource name parameter, and provides a default pattern constraint for resource names. #### Defining Operations with Scope Parameters -The `Extension` namespace provides operation templates that take a scope parameter, allowing you to define a single set of operations that can be reused across different target scopes. Define a parameterized interface for your operations: +The `Extension` namespace provides operation templates that take a scope parameter, allowing you to define a single set of operations that can be reused across different target scopes. Define a parameterized interface for your operations like this: ```typespec interface EmplOps { @@ -115,12 +115,12 @@ interface EmplOps {} interface ManagementGroups extends EmplOps {} ``` -| Scope | Description | -| --------------------------- | ------------------------------------- | -| `Extension.ScopeParameter` | Any scope (uses a generic scope path) | -| `Extension.Tenant` | Tenant-level scope | -| `Extension.Subscription` | Subscription-level scope | -| `Extension.ResourceGroup` | Resource group-level scope | -| `Extension.ManagementGroup` | Management group-level scope | +| Scope | Description | +| --------------------------- | ----------------------------------------- | +| `Extension.ScopeParameter` | Any scope (uses a generic scope uri path) | +| `Extension.Tenant` | Tenant-level scope | +| `Extension.Subscription` | Subscription-level scope | +| `Extension.ResourceGroup` | Resource group-level scope | +| `Extension.ManagementGroup` | Management group-level scope | #### Targeting External Resources