Skip to content

"Extending" a resource to simplify syntax and support smart defaults #14655

@anthony-c-martin

Description

@anthony-c-martin

Note

I'll start by saying this idea has been floated around between a few of us for a while, but I couldn't find a write-up of an existing proposal. If one exists, then feel free to close this one and combine.

Warning

This is currently a work-in-progress

Problem Statement

One of Bicep's strengths is that the syntax written in a Bicep file is a very close representation of the underlying APIs. This allows us to support new APIs immediately, without requiring any extra work. However, there are some cons with this approach:

  1. Design choices that make sense for an API may be less ergonomic or unnecessarily verbose when written in Bicep.
  2. Resources can be hard to discover, because the type & api version both must be provided for the mapping to API request.
  3. It's hard to know what some of the default values are, so users are torn between providing them explicitly, or expecting the API to pick sensible defaults.

Modules

Modules arguably solve a lot of these problems, especially the extensive library under https://github.com/Azure/bicep-registry-modules. However, there are still some downsides I think worth discussing:

  1. As a module author, you are fully abstracting the API away from the consumer. If a new property is needed, this requires you to publish a new version of your module.
  2. There is a performance overhead with using modules, because they result in extra deployments being created. This is something we've been working to optimize, but will still remain non-zero.

Proposal

Whereas a module is somewhat analogous to the OOP concept of "composition", it feels like there might also be a place in the language for a concept analogous to "inheritance": https://en.wikipedia.org/wiki/Composition_over_inheritance.

Basic Example

  1. Introduce a new means of sharing a partially complete resource - for example:
@export()
resource secureStorageAccount 'Microsoft.Compute/virtualMachines@...' abstract = {
  properties: {
    @overridable(false)
    allowSharedKeyAccess: false
    @overridable(false)
    isLocalUserEnabled: false
    @overridable(false)
    minimumTlsVersion: 'TLS1_2'
    ...
  }
}
  1. Usage:
import { secureStorageAccount } from 'simplifiedresources.bicep'

resource sa secureStorageAccount = {
  name: 'blah'
  properties: {
    allowSharedKeyAccess: true // raises an error
    accessTier: 'Hot' // other properties can be used as usual
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    discussionThis is a discussion issue and not a change proposal.enhancementNew feature or requestproposal

    Type

    No type

    Projects

    Status

    Todo

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions