Skip to content
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

Compile-time explicit validation on custom types #9571

Closed
WhitWaldo opened this issue Jan 18, 2023 · 0 comments · Fixed by #9870
Closed

Compile-time explicit validation on custom types #9571

WhitWaldo opened this issue Jan 18, 2023 · 0 comments · Fixed by #9870
Assignees
Labels
enhancement New feature or request type system

Comments

@WhitWaldo
Copy link

WhitWaldo commented Jan 18, 2023

I can apply a collection of validation decorators on parameters to ensure that the string provided is greater or less than a number of characters, or that a number is within a range, or that a string contains one of a set of known values.

@minLength(2)
@maxLength(32)
param ResourceName string

@minValue(1)
@maxValue(100)
param InstanceCount int

@allowed([
  'First'
  'Second'
  'Third'
])
param SubnetName string

I would like to similarly apply such validation constraints on custom type parameters. I'd like to apply regex validation constraints as well, but that's already covered in another issue.

type ResourceIdentifier = {
  @minLength(36)
  @maxLength(36)
  subscriptionId: string
  @minLength(1)
  @maxLength(90)
  resourceGroupName: string
  @minLength(1)
  resourceName: string
}

Further, it'd be great if this validation weren't applied only at ARM deployment time, but also on the language server at development time to catch values being passed into a custom type between modules that violate these constraints (first just looking at constant values, but ideally later also incorporating constant folding functionality.

For example, I'd like to see this throw an error (not a warning since it would fail at run time):

//ModuleA.bicep
module Deployment './ModuleB.bicep' = {
  name: 'dp-thisThat'
  params: {
    KeyVault: {
      subscriptionId: '' //Oops, should have populated this
      resourceGroupName: 'MyRg'
      resourceName: 'MyKeyVault'
    }
  }
}


//ModuleB.bicep
targetScope = 'resourceGroup'

type resourceIdentifier = {
  @minLength(36)
  @maxLength(36)
  subscriptionId: string
  @minLength(1)
  @maxLength(90)
  resourceGroupName: string
  @minLength(1)
  resourceName: string
}

param KeyVault resourceIdentifier

resource MyKeyVault 'Microsoft.KeyVault/vaults@2022-07-01' existing = {
  name: KeyVault.resourceName
  scope: resourceGroup(KeyVault.subscriptionId, KeyVault.resourceGroupName)
}

Either because I forgot to populate the subscription ID at dev time or made a bad assumption about the output of some other module (which don't yet support custom types), this would flag during build/deployment and alert the developer to the error without waiting to discover it during the eventual deployment process.

Especially when coupling this explicit validation with my request to allow custom types on module outputs and deduplication of type definitions via importing, it would ensure that assumptions about what's being produced in the output actually meet downstream expectations. Taking ModuleB.bicep above, let's say it were target scoped to a resource group. When exporting a resourceIdentifier with these explicit validations on it:

//ModuleB.bicep
//...

output KeyVaultId resourceIdentifier = {
  subscriptionId: subscription().subscriptionId //I don't know this syntax is right - just scribbling this example off the top of my head
  resourceGroupName: resourceGroup().name
  resourceName: KeyVaultName
}

Here, we write out the key vault name and the subscription ID and resource group name of the current target scope and we'd get validation right there at development time that we properly populated the values in a way that we have reasonable assurances would work:

  • We know the input name is at least 1 character long, so it fits the output constraint
  • The subscription ID is always a GUID, so it's always going to be 36 characters long when returned by the system
  • The resource group name is required to be between 1 and 90 characters long, so if it's being returned by the system as it would here, it would have already passed registration validation, so it's valid - bit more on this over here.
@WhitWaldo WhitWaldo added the enhancement New feature or request label Jan 18, 2023
@ghost ghost added the Needs: Triage 🔍 label Jan 18, 2023
@WhitWaldo WhitWaldo changed the title Explicit validation on custom types Compile-time explicit validation on custom types Jan 18, 2023
@stephaniezyen stephaniezyen added this to the Committed Backlog milestone Feb 1, 2023
@jeskew jeskew self-assigned this Mar 1, 2023
@ghost ghost locked as resolved and limited conversation to collaborators May 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request type system
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

4 participants