Azure / bicep-types-az

Bicep type definitions for ARM resources
MIT License
84 stars 27 forks source link

bicep error "Values for request parameters are invalid: networkAcls.virtualNetworkRules[*].id" for resource `Microsoft.Storage/storageAccounts` #1555

Open wilson0x4d opened 1 year ago

wilson0x4d commented 1 year ago

Bicep version Bicep CLI version 0.16.2 (de7fdd2b33)

Describe the bug When creating resource Microsoft.Storage/storageAccounts the parameter id is rejecting a valid virtual network subnet identifier, same parameter and approach works for keyvault resources but fails for storageaccount resources.

To Reproduce create a vnet with a single subnet in its own resource group, reference the existing subnet from another bicep template as follows, the names used here are not relevant to the issue and can be substituted:

resource myVnetExample 'Microsoft.Network/virtualNetworks@2022-07-01' existing = {
  scope: resourceGroup('rg-example')
  name: 'vnet-example'
}

resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = {
  // other parameters omitted for brevity, considered irrelevant
  name: 'saexample'
  kind: 'StorageV2'
  properties: {
    networkAcls: {
      bypass: 'AzureServices'
      defaultAction: 'Deny'
      virtualNetworkRules: [
        {
          action: 'Allow'
          id: myVnetExample.properties.subnets[0].id
        }
      ]
    }
  }
}

upon attempting deployment, observe error:

Inner Errors: {"code": "InvalidValuesForRequestParameters", "target": "saexample", "message": "Values for request parameters are invalid: networkAcls.virtualNetworkRules[*].id. For more information, see - https://aka.ms/storagenetworkruleset"}

Additional context

  1. this experience is counter to the documentation and observed bicep functionality of other resources, for example the same approach works for keyvault resources.

  2. leveraging resourceId(...) results in the same error.

  3. passing in a 'hardcoded' id using a parameter causes an InternalServerError status for the deployment when viewed in Portal, parameter was in the format: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{vnetName}/subnets/{snetName}'

The error logged for the deployment in this scenario was:

{
    "status": "Failed",
    "error": {
        "code": "ResourceDeploymentFailure",
        "target": "/subscriptions/123/resourceGroups/rg-example/providers/Microsoft.Storage/storageAccounts/saexample",
        "message": "The response for resource had empty or invalid content."
    }
}

it would seem Microsoft.Storage/storageAccounts creation improperly implements this parameter?

Please advise.

alex-frankel commented 1 year ago

It does look like something is wrong on the Storage Accounts Resource Provider side - especially with the InternalServerError. Are you able to open a support ticket for this so this can be routed to the storage team?

ghost commented 1 year ago

Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @xgithubtriage. Please see https://aka.ms/biceptypesinfo for troubleshooting help.

Issue Details
**Bicep version** Bicep CLI version 0.16.2 (de7fdd2b33) **Describe the bug** When creating resource `Microsoft.Storage/storageAccounts` the parameter `id` is rejecting a valid virtual network subnet identifier, same parameter and approach works for keyvault resources but fails for storageaccount resources. **To Reproduce** create a vnet with a single subnet in its own resource group, reference the existing subnet from another bicep template as follows, the names used here are not relevant to the issue and can be substituted: ```bicep resource myVnetExample 'Microsoft.Network/virtualNetworks@2022-07-01' existing = { scope: resourceGroup('rg-example') name: 'vnet-example' } resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { // other parameters omitted for brevity, considered irrelevant name: 'saexample' kind: 'StorageV2' properties: { networkAcls: { bypass: 'AzureServices' defaultAction: 'Deny' virtualNetworkRules: [ { action: 'Allow' id: myVnetExample.properties.subnets[0].id } ] } } } ``` upon attempting deployment, observe error: `Inner Errors: {"code": "InvalidValuesForRequestParameters", "target": "saexample", "message": "Values for request parameters are invalid: networkAcls.virtualNetworkRules[*].id. For more information, see - https://aka.ms/storagenetworkruleset"}` **Additional context** 1. this experience is counter to the documentation and observed bicep functionality of other resources, for example the same approach works for keyvault resources. 2. leveraging `resourceId(...)` results in the same error. 3. passing in a 'hardcoded' id using a parameter causes an `InternalServerError` status for the deployment when viewed in Portal, parameter was in the format: `'/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{vnetName}/subnets/{snetName}'` The error logged for the deployment in this scenario was: ``` { "status": "Failed", "error": { "code": "ResourceDeploymentFailure", "target": "/subscriptions/123/resourceGroups/rg-example/providers/Microsoft.Storage/storageAccounts/saexample", "message": "The response for resource had empty or invalid content." } } ``` it would seem `Microsoft.Storage/storageAccounts` creation improperly implements this parameter? Please advise.
Author: wilson0x4d
Assignees: -
Labels: `Needs: Triage :mag:`, `Service Attention`, `Storage`
Milestone: -
lsuarez5280 commented 1 year ago

Just to add more context if someone reads this while patching the service provider, it's the action: 'Allow' in the ACL definition that causes a 500 error on deployment of a new resource. Removing it allows for an initial deploy, but if the deploy is rerun, this is when preflight validation fails with the message:

{
  "code": "InvalidValuesForRequestParameters",
  "target": "mystorage",
  "message": "Values for request parameters are invalid: networkAcls.virtualNetworkRules[*].id. For more information, see - https://aka.ms/storagenetworkruleset"
}
maskati commented 1 year ago

There is something strange with the way the Storage RP is handling virtualNetworkRules. Assume we have in Bicep resource vnet 'Microsoft.Network/virtualNetworks@2022-01-01' existing, then the following succeeds:

Bicep: virtualNetworkRules: map([vnet.properties.subnets[0].id], subnetId => {id: subnetId}) Corresponding ARM: "virtualNetworkRules": "[map(createArray(reference(resourceId('Microsoft.Network/virtualNetworks', 'vnet'), '2022-01-01').subnets[0].id), lambda('subnetId', createObject('id', lambdaVariables('subnetId'))))]"

And the following fails with Values for request parameters are invalid: networkAcls.virtualNetworkRules[*].id:

Bicep: virtualNetworkRules: [{id: vnet.properties.subnets[0].id}] Corresponding ARM: "virtualNetworkRules": [{"id":"[reference(resourceId('Microsoft.Network/virtualNetworks', 'vnet'), '2022-01-01').subnets[0].id]"}]

These expressions resolve to the same array containing a single (first) subnet of vnet. The difference is only that the succeeding version is wrapped in a map function with createObject. It seems the Storage RP validation is broken.

Ruud2000 commented 1 year ago

Just wasted half a day on this to issue before finding this GitHub issue. Any estimate on when this issue will be resolved?

@maskati thanks for sharing the workaround using the map function! I just needed to ensure I retrieved the existing vnet resource within the same bicep module. I couldn't get it to work when I used the map function with output from another bicep module.

MasoudSamadi commented 1 week ago

Is there any update on this issue? I still have issues when using it like this: resource storageaccount 'Microsoft.Storage/storageAccounts@2023-05-01' = { name: storageaccountname location: location kind: 'StorageV2' sku: { name: 'Standard_LRS' } properties: { networkAcls: { defaultAction: 'Deny' virtualNetworkRules: [ { id: virtualNetwork.properties.subnets[0].id action: 'Allow' } { id: virtualNetwork.properties.subnets[1].id action: 'Allow' } ] } } }

kleieryan commented 3 days ago

I would also really appreciate an update on this. I hit this error today and the workaround above is not working for me. When I use the map workaround the deployment fails with "The resource namespace 'subscriptions' is invalid." And in any case I can't assume that the subnet I need to reference is always going to be at position 0 in Vnet.properties.subnets.

Including any kind of property or variable in the Id field of the virtualNetworkRule causes the same Values for request parameters are invalid: networkAcls.virtualNetworkRules[*].id: error.

This works;

var SubnetId = '/subscriptions/4f86752d-7030-4e15-b9a9-22fb7b8adfb6/resourceGroups/ResourceGroup123/providers/Microsoft.Network/virtualNetworks/POC-VNET/subnets/poc-subnet'
var StorageAccountVirtualNetworkRules = [
  {
    id: SubnetId
    action: 'Allow'
  }
]

Fails with Values for request parameters are invalid: networkAcls.virtualNetworkRules[*].id:

var SubscriptionId = subscription().id
var SubnetId = '/subscriptions/${SubscriptionId}/resourceGroups/ResourceGroup123/providers/Microsoft.Network/virtualNetworks/POC-VNET/subnets/poc-subnet'
var StorageAccountVirtualNetworkRules = [
  {
    id: SubnetId
    action: 'Allow'
  }
]

In other words, the only way I can get this to work is if I pass in a hard-coded resource Id string for the Subnet. See edit below

**Edit: apologies, realised i should have been using subscription().subscriptionId instead of subscription().Id so it is in fact possible to compute the resource Id using properties like this;

var StorageAccountVirtualNetworkRules = [
  {
    id: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${VnetResourceGroupName}/providers/Microsoft.Network/virtualNetworks/${Vnet.name}/subnets/${Subnet.name}'
    action: 'Allow'
  }
]