Azure / PSRule.Rules.Azure

Rules to validate Azure resources and infrastructure as code (IaC) using PSRule.
https://azure.github.io/PSRule.Rules.Azure/
MIT License
389 stars 84 forks source link

[ERROR] Failed to expand bicep source: Cannot process argument because the value of argument "name" is not valid. #2850

Closed maythamfahmi closed 4 months ago

maythamfahmi commented 4 months ago

Existing rule

Azure.AppService

Description of the issue

I have following userAssignedIdentities for Web app

identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${userAssignedScope}': {}
    }
  }

It works fine when I deploy it. But when I run PSRule, it fails with following error

[ERROR] Failed to expand bicep source '\Infrastructure\infra\main.dev-nb.bicepparam'. Exception calling "GetBicepParamResources" with "2" argument(s): "Cannot process argument because the value of argument "name" is not valid. Change the value of the "name" argument and run the operation again."    [ERROR] Failed to expand bicep source '\Infrastructure\infra\main.dev.bicepparam'. Exception calling "GetBicepParamResources" with "2" argument(s): "Cannot process argument because the value of argument "name" is not valid. Change the value of the "name" argument and run the operation again."   

image

Error messages

[ERROR] Failed to expand bicep source '\Infrastructure\infra\main.dev.bicepparam'. Exception calling "GetBicepParamResources" with "2" argument(s): "Cannot process argument because the value of argument "name" is not valid. Change the value of the "name" argument and run the operation again."

Reproduction

identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${userAssignedScope}': {}
    }
  }

gives the error when disabling

  identity: {
    type: 'UserAssigned'
    //userAssignedIdentities: {
    //  '${userAssignedScope}': {}
    //}
  }

PSRule Test works

But need to enable it again for deployment.

Version of PSRule

2.9.0

Version of PSRule for Azure

1.36.0

Additional context

When searching, I found this #2751 but it did not make me wiser.

BernieWhite commented 4 months ago

@maythamfahmi Thanks for reporting the error.

Are you able to provide a little more detail around userAssignedScope?

maythamfahmi commented 4 months ago

@maythamfahmi Thanks for reporting the error.

Are you able to provide a little more detail around userAssignedScope?

  • Is this a variable or parameter in a .bicep file?
  • If it is a parameter, is it set by an output from another module?
  • Can provide an example of where it is defined and where is it set?

Thanks, I am glad for your quick feedback, here is my answer: parameter in appService.bicep that takes the value from an output. As mentioned it deploys fine in Azure and works as expected, it is more psrule that comes with this error message.

Here is a minimized example of the code I have.

appService.bicep

param location string
param appServicePlanName string
param webAppName string
param userAssignedScope string

resource asp 'Microsoft.Web/serverfarms@2023-01-01' = {
  name: appServicePlanName
  location: location
  sku: {
    name: 'S1'
  }
}

resource webApp 'Microsoft.Web/sites@2023-01-01' = {
  name: webAppName
  location: location
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${userAssignedScope}': {}
    }
  }
  properties: {
    serverFarmId: asp.id
    httpsOnly: true
  }
}

userAssignedIdentities.bicep

param userAssignedName string
param location string

resource userAssignedIdentities 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-07-31-preview' = {
  name: userAssignedName
  location: location
}

output scope string = userAssignedIdentities.id
output principalObjectId string = userAssignedIdentities.properties.principalId
output clientId string = userAssignedIdentities.properties.clientId

main.bicep

module appService '../modules/appService/appService.bicep' = {
  name: 'WebApp-Deployment'
  scope: resourceGroup(rgAppService.name)
  params: {
    webAppName: '${appServiceName}'
    appServicePlanName: '${appServicePlanName}'
    location: location
    skuName: webAppSkuName
    userAssignedScope: userAssignedId.outputs.scope
  }
}

module userAssignedId '../modules/common/userAssignedIdentities.bicep' = {
  scope: resourceGroup(rgCommon.name)
  name: 'Identity-Deployment'
  params: {
    location: location
    userAssignedName: userAssignedIdentityName
  }
}
BernieWhite commented 4 months ago

@maythamfahmi Ok thanks for the additional detail.

Some follow up questions.

In the common case it would be something like below, because the resource id is required for the userAssignedIdentities block:


// ---------
// RESOURCES
// ---------

@sys.description('Create or update a User-Assigned Managed Identity.')
resource identity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: name
  location: location
}

// -------
// OUTPUTS
// -------

@sys.description('A unique identifier for the Managed Identity.')
output id string = identity.id
maythamfahmi commented 4 months ago

yes, I use output scope string = userAssignedIdentities.id, the same as output id string = identity.id

BernieWhite commented 4 months ago

Ok great. Thanks for the detail @maythamfahmi. That should allow us to track down the bug.

maythamfahmi commented 4 months ago

@BernieWhite I have made a little founding that might enlighten your debugging work. I did a review with my colleague Jonas, and he suggested for fun trying to harden the id. Funny enough the PSRule works fine.

So when testing with this it works:

userAssignedIdentities: { '/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg-name/providers/Microsoft.ManagedIdentity/userAssignedIdentities/id-name': {} }

And the other things, when I use following with Microsoft.Sql/servers@2023-08-01-preview

identity: { type: 'UserAssigned' userAssignedIdentities: { '${userAssignedScope}': {} } }

it works, so the issue with testing is related to Microsoft.Web/sites@2023-01-01 but again, this is my assumption.

So in short this is the workaround

'/subscriptions/${subscription().subscriptionId}/resourcegroups/${rgName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${userAssignedIdentityName}'

The string for this workaround is the same as the identity.id

BernieWhite commented 4 months ago

@maythamfahmi The issue is cause by the resource IDs for the module deployments being incorrectly generated when you have a subscription level target scope and modules targeted to a resource group scope.

As a result the managed identity dependency is not being resolved before the app service module uses it.


A fix will be available in the next pre-release, available in the next few days. As a workaround:

maythamfahmi commented 3 months ago

@BernieWhite just to let you know, the same issue is happening for Microsoft.Cdn/profiles@2024-02-01

BernieWhite commented 3 months ago

@maythamfahmi OK, thanks. This is also for v1.36.0 or are you trying with a v1.37.0 preview?

maythamfahmi commented 3 months ago

@BernieWhite 😊I still using 1.36.0, I will try with 1.37.0 preview and let you know