Closed ms-henglu closed 2 years ago
There're 2 options:
scope
attribute, defaults to ResourceGroup
scope.bicep-types-az
, scope
can be inferred from type
, but new resource can't be supported without the latest bicep-types-az
We still need to be able to provide the target of the scope, even if we infer the scope from the type. For example, if the scope is Management group, which management group should it be created in? Possibly use a scope property to reference the ID of the target.
We can reuse the parent_id
to get the target scope, for example, the target management group.
Let me add more details.
def:
Root Resource / Top-Level Resource
: A resource with only a single level of nested types (i.e. there's just a single type after the RP namespace). Microsoft.Network/networkSecurityGroups
is a top-level resource, whereas Microsoft.Network/networkSecurityGroups/securityRules
is not. Child Resource / Nested Resource
: A resource with two or more levels of nested types. Parent Resource
: The parent to a child resource, identified by removing a level of nesting from the resource type. Microsoft.Network/networkSecurityGroups
is the parent to Microsoft.Network/networkSecuriyGroups/securityRules
.scopes:
Tenant Scope
/
or empty/providers/Microsoft.Somthing
Subscription Scope
/subscriptions/{subscriptionId}/
/subscriptions/{subscriptionId}/providers/Microsoft.Somthing
ResourceGroup Scope
/subscriptions/{subscriptionId}/resourceGroups/{groupName}/
which is the id of a resource group/subscriptions/{subscriptionId}/resourceGroups/{groupName}/providers/Microsoft.Something
Extension Scope
ManagementGroup Scope
/providers/Microsoft.Management/managementGroups/{managementGroupName}/
which is the id of a management group/providers/Microsoft.Management/managementGroups/{managementGroupName}/providers/Microsoft.Something
However, there still are some edge cases, like if the scope from bicep types is unknown, or a type is not in the bicep types. In those cases, we can't infer the correct scope from type
, but if user uses parent_id
following above rule, we can manage these resources.
https://github.com/Azure/terraform-provider-azurerm-restapi/pull/42 is the implementation about above solution which supports other scopes resources without introducing new property.
I've added lots of tests to guarantee that a correct resource id can be built from parent_id
name
and type
, also added e2e tests to manage resource group(subscription scope), resource lock(extension scope), and many common resources(resource group scope).
But I don't have permission to create resource over tenant scope and mgmt group scope, I'll do more tests.
Here is a document about how to build resource id from parent id, name and type. https://github.com/Azure/terraform-provider-azurerm-restapi/blob/main/docs/resource_id.md
This feature has been supported, so I'll close this issue.
Hello It seems that the following code doesn't support extension on anything else than resource group. https://github.com/Azure/terraform-provider-azapi/blob/e53a2e48d676da9d01efea6eb240736f7d6374bc/internal/services/parse/resource.go#L193-L202
this means it would not be possible to create costallocationrules since it's a billingAccount extension.
I found the following workaround by abusing the validation code, but it's not pretty... Would it be possible to add other extension type?
resource "azapi_resource" "cost_allocation_rules" {
for_each = { for rule in var.cost_allocation_rules_resource_group : rule.sourceResourceGroupName => rule }
type = "costAllocationRules@2023-11-01" # As long as it's doesn't contain "/" it's fine
name = "Microsoft.CostManagement/costAllocationRules/${each.value["sourceResourceGroupName"]}-to-${data.azurerm_subscription.target.display_name}"
parent_id = "/providers/Microsoft.Billing/billingAccounts/${var.billing_account_id}"
/*
case !strings.Contains(azureResourceType, "/"):
// case 0: resource type is a provider type
// avoid duplicated `/` if parent_id is tenant scope
scopeId := parentId
if parentId == "/" {
scopeId = ""
}
azureResourceId = fmt.Sprintf("%s/providers/%s", scopeId, name)
but for this to work we have to pass an arbritary resource type
and thus disable schema validation
*/
schema_validation_enabled = false
body = jsonencode({...})
}
Here're the list extracted from bicep-types-az