-
Notifications
You must be signed in to change notification settings - Fork 735
Document x-ms-arm-id-details extension #4150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2945111
75c6072
ca3fc29
0bfa232
c4f652e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,6 +33,7 @@ The following documents describes AutoRest specific vendor extensions for [OpenA | |
| - [x-ms-azure-resource](#x-ms-azure-resource) - indicates that the [Definition Schema Object](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#schemaObject) is a resource as defined by the [Resource Manager API](https://msdn.microsoft.com/en-us/library/azure/dn790568.aspx) | ||
| - [x-ms-request-id](#x-ms-request-id) - allows to overwrite the request id header name | ||
| - [x-ms-client-request-id](#x-ms-client-request-id) - allows to overwrite the client request id header name | ||
| - [x-ms-arm-id-details](#x-ms-arm-id-details) - indicates the allowed resources that can be referred to by an `arm-id` formatted string field. | ||
|
|
||
| ### Metadata extensions | ||
|
|
||
|
|
@@ -1192,6 +1193,150 @@ When set, specifies the header parameter to be used instead of `x-ms-client-requ | |
| } | ||
| ``` | ||
|
|
||
| ## x-ms-arm-id-details | ||
|
|
||
| Can only be set on `"type": "string"` fields with `"format": "arm-id"`. | ||
|
|
||
| When set, specifies the set of resource types which can be referenced by this `arm-id`. If this extension isn't provided for a particular `arm-id`, the field can refer to any valid ARM ID. | ||
|
|
||
| **Parent element**: [Parameter Object](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#parameterObject), [Schema Object](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#schemaObject), or [Items Object](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#itemsObject) | ||
|
|
||
| ### Schema | ||
|
|
||
| | Field Name | Type | Description | | ||
| | ---------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | allowedResources | `[AllowedResource]` | **Required** An array of allowed ARM resources. Each element represents a particular type of ARM resource which can be referred to by this `arm-id`. | | ||
|
|
||
| **AllowedResource schema**: | ||
|
|
||
| | Field Name | Type | Description | | ||
| | ---------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | scopes | `[string]` | An array of scopes. See [Allowed Scopes](#allowed-scopes). If not specified, the default scope is `["ResourceGroup"]`. | | ||
| | type | `string` | **Required** The type of resource that is being referred to. For example `Microsoft.Network/virtualNetworks` or `Microsoft.Network/virtualNetworks/subnets`. See [Example Types](#example-types) for more examples. | | ||
|
|
||
| #### Allowed Scopes | ||
|
|
||
| The following values are allowed for `scopes`. These values were derived from the [scope field in ARM templates](https://docs.microsoft.com/azure/azure-resource-manager/templates/scope-extension-resources?tabs=azure-cli). | ||
| | Scope | URL prefix | Meaning | | ||
| | ----------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | `Tenant` | `/` | The resource is deployed into a tenant | | ||
| | `Subscription` | `/subscriptions/{subscriptionId}/` | The resource is deployed into a subscription | | ||
| | `ResourceGroup` | `/subscriptions/{subscriptionId}/resourceGroups/{group}` | The resource is deployed into a resource group | | ||
| | `ManagementGroup` | `/providers/Microsoft.Management/managementGroups/{managementGroupName}/` | The resource is deployed into a management group | | ||
| | `Extension` | `{parentScope}/providers/{extensionNamespace}/{extensionType}/{extensionName}/` | The resource is an extension resource and may be deployed as a subresource of another resource. `parentScope` may be a resource in any of the above scopes. | | ||
| | `*` | Any of the above | The resource may be deployed into any of the above scopes. This is identical to `["Tenant", "Subscription", "ResourceGroup", "ManagementGroup", "Extension"`] | | ||
|
|
||
| #### Example Types | ||
|
|
||
| Below is a table showing an example entry for various different kinds of resource types | ||
|
|
||
| | Resource kind | Example | | ||
| | -------------------------------------- | ---------------------------------------------------------------------------- | | ||
| | Resource in a tenant | `{"scopes": ["Tenant"], "type": "Microsoft.Capacity/reservationOrders"}` | | ||
| | Resource in a subscription | `{"scopes": ["Subscription"], "type": "Microsoft.Resources/resourceGroups"}` | | ||
| | Resource in a resource group | `{"scopes": ["ResourceGroup"], "type": "Microsoft.Network/virtualNetworks"}` | | ||
| | Resource in a management group | `{"scopes": ["ManagementGroup"], "type": "Microsoft.Blueprint/blueprints"}` | | ||
| | Extension resource | `{"scopes": ["Extension"], "type": "Microsoft.Authorization/locks"}` | | ||
| | Any resource in resource group | `{"scopes": ["ResourceGroup"], "type": "*"}` | | ||
| | Any compute resource in resource group | `{"scopes": ["ResourceGroup"], "type": "Microsoft.Compute/*"}` | | ||
|
|
||
| Sub-resources are specified in the same manner as their parent resource but with additional paths on the end. For example to refer to a subnet: `Microsoft.Network/virtualNetworks/subnets`. | ||
|
|
||
| **Note** that we do not currently support limiting references to an extension resource by the kind of resource it is on. For example you can refer to _any_ resource lock (`Microsoft.Authorization/locks`) but not to a resource lock but only when it's on a CosmosDB. | ||
|
|
||
| #### Examples | ||
|
|
||
| **Example**: An `arm-id` field that can refer to any ARM resource ID. | ||
|
|
||
| ```json5 | ||
| "MyExampleType": { | ||
| "properties": { | ||
| "id": { | ||
| "type": "string", | ||
| "format": "arm-id" | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| **Example**: An `arm-id` field that must refer to a virtual network | ||
|
|
||
| ```json5 | ||
| "MyExampleType": { | ||
| "properties": { | ||
| "vnetId": { | ||
| "type": "string", | ||
| "format": "arm-id", | ||
| "x-ms-arm-id-details": { | ||
matthchr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| "allowedResources": [ | ||
| { | ||
| "type": "Microsoft.Network/virtualNetworks" | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| **Example (preferred)**: An `arm-id` field with no additional information about what kind of resource it must refer to, referring to the common type. | ||
|
|
||
| ```json5 | ||
| "MyExampleType": { | ||
| "properties": { | ||
| "id": { | ||
| "$ref": "../../../../../common-types/resource-management/v2/types.json#/definitions/ArmId", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what's the common type 'ArmId' for ?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @johanste mentioned that he thought it would be useful to have a shared type in the common defs (like we do for |
||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| **Example (preferred)**: An `arm-id` field that must refer to a virtual network, via a referenced definition | ||
|
|
||
| ```json5 | ||
| "MyExampleType": { | ||
| "properties": { | ||
| "vnetId": { | ||
| "$ref": "#/definitions/VNetId", | ||
| } | ||
| } | ||
| }, | ||
| "VNetId": { | ||
| "type": "string", | ||
| "format": "arm-id", | ||
| "x-ms-arm-id-details": { | ||
| "allowedResources": [ | ||
| { | ||
| "type": "Microsoft.Network/virtualNetworks" | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| **Example**: An array of `arm-id`'s that refer to a subnet | ||
|
|
||
| ```json5 | ||
| "MyExampleType": { | ||
| "properties": { | ||
| "vnets": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "string", | ||
| "format": "arm-id", | ||
| "x-ms-arm-id-details": { | ||
| "allowedResources": [ | ||
| { | ||
| "type": "Microsoft.Network/virtualNetworks/subnets" | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## x-nullable | ||
|
|
||
| Set `"x-nullable": true` on a schema to indicate that a `null` is a legal value. By default, a `null` value should be disallowed when forming a request and rejected during payload deserialization. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are the thoughts on how scopes should be interpreted? Does this apply a restriction to the same tenant / subscription / resource group / management group as the referring resource, or something else?
I worry about making this too deployment-specific. It would be nice to apply this in general to encode actual 'locality' restrictions that could also be used both for smart tools to validate an input reference or for for smart tools to deploy the resource. One such restriction would be 'location', for resources that must be in the same region as the referring resource.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hadn't thought about "the referenced resource must be in the same region/tenant/subscription as the current resource". That's an interesting angle and we could definitely consider expanding this proposal to cover that case as well. Scope as proposed is about the ability to restrict what deployment locations are allowed for the given resource type.
So you would read
{"scopes": ["ResourceGroup"], "type": "Microsoft.Network/virtualNetworks"}as "This property must refer to an ARM ID pointing to a virtual network rooted in a resource group". There's no requirement of what subscription that RG is in. If you were to validate this ARM ID with a regex it would look something like/subscriptions/[a-zA-Z0-0-]+/resourceGroups/[a-zA-Z0-0-]+/Microsoft.Network/virtualNetworks/[a-zA-Z0-0-]+. This reference explicitly disallows aMicrosoft.Network/virtualNetworksdeployed elsewhere, say in a management group (That's probably not allowed today but some resources are dual-homed I believe).Services that don't care can use ``{"scopes": ["*"], "type": "Microsoft.Network/virtualNetworks"}
. This is the same concept ofscope` that is proposed/discussed in @majastrz's document as well. It's really just a shorthand for `/subscriptions/{}/resourceGroups/{}` (and the various other scope prefixes).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, management groups typically sit 'above' subscriptions, so, unless I am wildly mistaken, you can only deploy a virtual network to a resource group. Management Groups are a good deployment location for extension resources, but don't apply to resources that are Tracked Resources or Subscription resources, or resource group resources.
I guess here, you want to be able to deploy the resource without having to know anything about the properties of the resource type, is that correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, exactly. Maybe I need to do some documentation improvements (or we need to pick a different name than
Scope?). As discussed over teams the issue is that this is a reference to a sayMicrosoft.Network/virtualnetworks, and at the reference site there's no knowledge of what that thing looks like. The objective for this annotation would be that client tools could give better hints/warnings about ARM references, so ideally given this annotation we can look at an ARM ID and confirm if it's valid. Without ascopesection though we couldn't confirm that:/subscriptions/<id>/Microsoft.Network/virtualNetworks/myVnetwas an invalid reference, because it's not at the right scope.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say, this is good for the first version, and perhaps we can augment this later with some restrictions around the resource (for example, that it has to be in the same region,