-
Notifications
You must be signed in to change notification settings - Fork 92
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
feat: Added diverse specs for User-defined types #1738
base: main
Are you sure you want to change the base?
Changes from all commits
027d408
34b0ae7
cf72496
46da669
0cae562
5048e15
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,46 @@ | ||||||
--- | ||||||
title: BCPRMNFR2 - User-defined types - AVM-Common-Types | ||||||
url: /spec/BCPRMNFR2 | ||||||
geekdocNav: true | ||||||
geekdocAlign: left | ||||||
geekdocAnchor: true | ||||||
type: posts | ||||||
tags: [ | ||||||
Class-Resource, # MULTIPLE VALUES: this can be "Class-Resource" AND/OR "Class-Pattern" AND/OR "Class-Utility" | ||||||
Type-NonFunctional, # SINGLE VALUE: this can be "Type-Functional" OR "Type-NonFunctional" | ||||||
Category-Inputs/Outputs, # SINGLE VALUE: this can be "Category-Testing" OR "Category-Telemetry" OR "Category-Contribution/Support" OR "Category-Documentation" OR "Category-CodeStyle" OR "Category-Naming/Composition" OR "Category-Inputs/Outputs" OR "Category-Release/Publishing" Language-Bicep, # MULTIPLE VALUES: this can be "Language-Bicep" AND/OR "Language-Terraform" | ||||||
Severity-MUST, # SINGLE VALUE: this can be "Severity-MUST" OR "Severity-SHOULD" OR "Severity-MAY" | ||||||
Persona-Owner, # MULTIPLE VALUES: this can be "Persona-Owner" AND/OR "Persona-Contributor" | ||||||
Persona-Contributor, # MULTIPLE VALUES: this can be "Persona-Owner" AND/OR "Persona-Contributor" | ||||||
Lifecycle-BAU, # SINGLE VALUE: this can be "Lifecycle-Initial" OR "Lifecycle-BAU" OR "Lifecycle-EOL" | ||||||
Validation-TBD # SINGLE VALUE: this can be "Validation-Manual" OR "Validation-CI/Informational" OR "CI/Enforced" | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use the right value for new specs? AFAIK the intention going forward is to assign the tacmg based on the current static validation situation, and update it every time we update static validation in BRM.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This applies to all specs below |
||||||
] | ||||||
priority: 13010 | ||||||
--- | ||||||
|
||||||
#### ID: BCPRMNFR2 - Category: User-defined types - AVM-Common-Types | ||||||
|
||||||
When implementing any of the [shared](/Azure-Verified-Modules/specs/shared/interfaces) or [Bicep-specific](/Azure-Verified-Modules/specs/bicep/interfaces) AVM interface variants you MUST import their User-defined type (UDT) via the published [AVM-Common-Types](https://github.com/Azure/bicep-registry-modules/tree/main/avm/utl/types/avm-common-types) module. | ||||||
|
||||||
When doing so, each type MUST be imported separately, right above the parameter or output that uses it. | ||||||
|
||||||
```bicep | ||||||
import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:*.*.*' | ||||||
@description('Optional. Array of role assignments to create.') | ||||||
param roleAssignments roleAssignmentType[]? | ||||||
import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:*.*.*' | ||||||
@description('Optional. The diagnostic settings of the service.') | ||||||
param diagnosticSettings diagnosticSettingFullType[]? | ||||||
``` | ||||||
|
||||||
Importing them individually as opposed to one common block has several benefits such as | ||||||
- Individual versioning of types | ||||||
- If you must update the version for one type, you're not exposed to unexpected changes to other types | ||||||
|
||||||
{{< hint type=important >}} | ||||||
|
||||||
The `import (...)` block MUST not be added in between a parameter's definition and its metadata. Doing so breaks the metadata's binding to the parameter in question. | ||||||
|
||||||
{{< /hint >}} | ||||||
|
||||||
Finally, you should check for version updates regularly to ensure the resource module stays consistent with the specs. If the used AVM-Common-Types runs stale, the CI may eventually fail the module's static tests. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
--- | ||
title: BCPNFR1 - Data Types | ||
title: BCPNFR1 - User-defined types - General | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this one should temporarily be a SHOULD and not a MUST |
||
url: /spec/BCPNFR1 | ||
geekdocNav: true | ||
geekdocAlign: left | ||
|
@@ -20,7 +20,7 @@ tags: [ | |
priority: 11010 | ||
--- | ||
|
||
#### ID: BCPNFR1 - Category: Inputs - Data Types | ||
#### ID: BCPNFR1 - Category: Inputs - User-defined types - General | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @AlexanderSehr, I know this is not here to be reviewed yet, but I want to add an important comment: be aware that if you change this title, it will start breaking legacy links that are still pointing to the specs present on the old shared and Bicep/TF specific pages. This is unavoidable, and I'm not saying you shouldn't rename an article if the name is off, but you need to be aware of this side effect. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hey @matebarabas, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So... can this comment be resolved, @matebarabas? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can any applicable link be updated via search and replace? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
No, as the ones I was referring to are auto-generated based on the title. I agree to Alex's comment on not prioritizing backward compatibility if we feel something is just simply off. Feel free to resolve this.
Yes please, that's what I was hoping to express by sending a thumb-up on your comment. :) I knew I should've been more explicit. :) |
||
|
||
To simplify the consumption experience for module consumers when interacting with complex data types input parameters, mainly objects and arrays, the Bicep feature of [User-Defined Types](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/user-defined-data-types) **MUST** be used and declared. | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,38 @@ | ||||||
--- | ||||||
title: BCPNFR18 - User-defined types - Specification | ||||||
url: /spec/BCPNFR18 | ||||||
geekdocNav: true | ||||||
geekdocAlign: left | ||||||
geekdocAnchor: true | ||||||
type: posts | ||||||
tags: [ | ||||||
Class-Resource, # MULTIPLE VALUES: this can be "Class-Resource" AND/OR "Class-Pattern" AND/OR "Class-Utility" | ||||||
Class-Pattern, # MULTIPLE VALUES: this can be "Class-Resource" AND/OR "Class-Pattern" AND/OR "Class-Utility" | ||||||
Type-NonFunctional, # SINGLE VALUE: this can be "Type-Functional" OR "Type-NonFunctional" | ||||||
Category-Inputs/Outputs, # SINGLE VALUE: this can be "Category-Testing" OR "Category-Telemetry" OR "Category-Contribution/Support" OR "Category-Documentation" OR "Category-CodeStyle" OR "Category-Naming/Composition" OR "Category-Inputs/Outputs" OR "Category-Release/Publishing" | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm getting confused between the title and this label. Should we add a label Category-UserDefinedTypes? Or are all falling into the Inputs/Outputs label? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @eriqua, this is used to control under which section of the specs page in question (e.g. bicep res page) the given spec will show up. Introducing anything new would require the shortcode and the page structure to be updated, so I strongly recommend trying to categorize what we need under one of the existing categories. These could work imho:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then I'm not sure of how useful categories are and I'm afraid we're locking ourselves into a process we ourselves enforced. Don't get me wrong but we are saying that adding a new label would be too complex and we prefer to enforce a different, not ideal one instead to overcome that complexity. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I tried to write it in a way that at least one of the specs shows up on two pages by adding both tags. I think that worked :D If I'm not mistaken I did that because it was for inputs & naming |
||||||
Language-Bicep, # MULTIPLE VALUES: this can be "Language-Bicep" AND/OR "Language-Terraform" | ||||||
Severity-MUST, # SINGLE VALUE: this can be "Severity-MUST" OR "Severity-SHOULD" OR "Severity-MAY" | ||||||
Persona-Owner, # MULTIPLE VALUES: this can be "Persona-Owner" AND/OR "Persona-Contributor" | ||||||
Persona-Contributor, # MULTIPLE VALUES: this can be "Persona-Owner" AND/OR "Persona-Contributor" | ||||||
Lifecycle-BAU, # SINGLE VALUE: this can be "Lifecycle-Initial" OR "Lifecycle-BAU" OR "Lifecycle-EOL" | ||||||
Validation-TBD # SINGLE VALUE: this can be "Validation-Manual" OR "Validation-CI/Informational" OR "CI/Enforced" | ||||||
] | ||||||
priority: 11010 | ||||||
--- | ||||||
|
||||||
#### ID: BCPNFR18 - Category: User-defined types - Specification | ||||||
|
||||||
User-defined types (UDTs) MUST always be singular and non-nullable. The configuration of either should instead be done directly at the parameter or output that uses the type. | ||||||
|
||||||
For example, instead of | ||||||
```bicep | ||||||
param subnets subnetsType | ||||||
type subnetsType = { ... }[]? | ||||||
``` | ||||||
the type should instead be defined like | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
```bicep | ||||||
param subnets subnetType[]? | ||||||
type subnetType = { ... } | ||||||
``` | ||||||
|
||||||
The primary reason for this requirement is clarity. If not defined directly at the parameter or output, a user would always be required to check the type to understand how e.g., a parameter is expected. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
--- | ||
title: BCPNFR19 - User-defined types - Naming | ||
url: /spec/BCPNFR18 | ||
geekdocNav: true | ||
geekdocAlign: left | ||
geekdocAnchor: true | ||
type: posts | ||
tags: [ | ||
Class-Resource, # MULTIPLE VALUES: this can be "Class-Resource" AND/OR "Class-Pattern" AND/OR "Class-Utility" | ||
Class-Pattern, # MULTIPLE VALUES: this can be "Class-Resource" AND/OR "Class-Pattern" AND/OR "Class-Utility" | ||
Type-NonFunctional, # SINGLE VALUE: this can be "Type-Functional" OR "Type-NonFunctional" | ||
Category-Inputs/Outputs, # SINGLE VALUE: this can be "Category-Testing" OR "Category-Telemetry" OR "Category-Contribution/Support" OR "Category-Documentation" OR "Category-CodeStyle" OR "Category-Naming/Composition" OR "Category-Inputs/Outputs" OR "Category-Release/Publishing" | ||
Category-Naming/Composition, # SINGLE VALUE: this can be "Category-Testing" OR "Category-Telemetry" OR "Category-Contribution/Support" OR "Category-Documentation" OR "Category-CodeStyle" OR "Category-Naming/Composition" OR "Category-Inputs/Outputs" OR "Category-Release/Publishing" | ||
Language-Bicep, # MULTIPLE VALUES: this can be "Language-Bicep" AND/OR "Language-Terraform" | ||
Severity-MUST, # SINGLE VALUE: this can be "Severity-MUST" OR "Severity-SHOULD" OR "Severity-MAY" | ||
Persona-Owner, # MULTIPLE VALUES: this can be "Persona-Owner" AND/OR "Persona-Contributor" | ||
Persona-Contributor, # MULTIPLE VALUES: this can be "Persona-Owner" AND/OR "Persona-Contributor" | ||
Lifecycle-BAU, # SINGLE VALUE: this can be "Lifecycle-Initial" OR "Lifecycle-BAU" OR "Lifecycle-EOL" | ||
Validation-TBD # SINGLE VALUE: this can be "Validation-Manual" OR "Validation-CI/Informational" OR "CI/Enforced" | ||
] | ||
priority: 11010 | ||
--- | ||
|
||
#### ID: BCPNFR19 - Category: User-defined types - Naming | ||
|
||
User-defined types (UDTs) MUST always end with the suffix `(...)Type` to make them obvious to users. In addition it is recommended to extend the suffix to `(...)OutputType` if a UDT is exclusively used for outputs. | ||
```bicep | ||
type subnet = { ... } // Wrong | ||
type subnetType = { ... } // Correct | ||
type subnetOutputType = { ... } // Correct, if used only for outputs | ||
``` | ||
|
||
Since User-defined types (UDTs) MUST always be singular as per [BCPNFR18](#id-bcpnfr18---category-user-defined-types---specification), their naming should reflect this and also be singular. | ||
```bicep | ||
type subnetsType = { ... } // Wrong | ||
type subnetType = { ... } // Correct | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
--- | ||
title: BCPNFR20 - User-defined types - Export | ||
url: /spec/BCPNFR20 | ||
geekdocNav: true | ||
geekdocAlign: left | ||
geekdocAnchor: true | ||
type: posts | ||
tags: [ | ||
Class-Resource, # MULTIPLE VALUES: this can be "Class-Resource" AND/OR "Class-Pattern" AND/OR "Class-Utility" | ||
Class-Pattern, # MULTIPLE VALUES: this can be "Class-Resource" AND/OR "Class-Pattern" AND/OR "Class-Utility" | ||
Type-NonFunctional, # SINGLE VALUE: this can be "Type-Functional" OR "Type-NonFunctional" | ||
Category-Inputs/Outputs, # SINGLE VALUE: this can be "Category-Testing" OR "Category-Telemetry" OR "Category-Contribution/Support" OR "Category-Documentation" OR "Category-CodeStyle" OR "Category-Naming/Composition" OR "Category-Inputs/Outputs" OR "Category-Release/Publishing" | ||
Language-Bicep, # MULTIPLE VALUES: this can be "Language-Bicep" AND/OR "Language-Terraform" | ||
Severity-MUST, # SINGLE VALUE: this can be "Severity-MUST" OR "Severity-SHOULD" OR "Severity-MAY" | ||
Persona-Owner, # MULTIPLE VALUES: this can be "Persona-Owner" AND/OR "Persona-Contributor" | ||
Persona-Contributor, # MULTIPLE VALUES: this can be "Persona-Owner" AND/OR "Persona-Contributor" | ||
Lifecycle-BAU, # SINGLE VALUE: this can be "Lifecycle-Initial" OR "Lifecycle-BAU" OR "Lifecycle-EOL" | ||
Validation-TBD # SINGLE VALUE: this can be "Validation-Manual" OR "Validation-CI/Informational" OR "CI/Enforced" | ||
] | ||
priority: 11010 | ||
--- | ||
|
||
#### ID: BCPNFR20 - Category: User-defined types - Export | ||
|
||
User-defined types (UDTs) SHOULD always be exported via the `@export()` annotation in every template they're implemented in. | ||
```bicep | ||
@export() | ||
type subnetType = { ... } | ||
``` | ||
|
||
Doing so has the benefit that other (e.g., parent) modules can import them and as such reduce code duplication. Also, if the module itself is published, users of the Public Bicep Registry can import the types independently of the module itself. One example where this can be useful is a pattern module that may re-use the same interface when referencing a module from the registry. |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,41 @@ | ||||||
--- | ||||||
title: BCPNFR21 - User-defined types - Decorators | ||||||
url: /spec/BCPNFR21 | ||||||
geekdocNav: true | ||||||
geekdocAlign: left | ||||||
geekdocAnchor: true | ||||||
type: posts | ||||||
tags: [ | ||||||
Class-Resource, # MULTIPLE VALUES: this can be "Class-Resource" AND/OR "Class-Pattern" AND/OR "Class-Utility" | ||||||
Class-Pattern, # MULTIPLE VALUES: this can be "Class-Resource" AND/OR "Class-Pattern" AND/OR "Class-Utility" | ||||||
Type-NonFunctional, # SINGLE VALUE: this can be "Type-Functional" OR "Type-NonFunctional" | ||||||
Category-Inputs/Outputs, # SINGLE VALUE: this can be "Category-Testing" OR "Category-Telemetry" OR "Category-Contribution/Support" OR "Category-Documentation" OR "Category-CodeStyle" OR "Category-Naming/Composition" OR "Category-Inputs/Outputs" OR "Category-Release/Publishing" | ||||||
Language-Bicep, # MULTIPLE VALUES: this can be "Language-Bicep" AND/OR "Language-Terraform" | ||||||
Severity-MUST, # SINGLE VALUE: this can be "Severity-MUST" OR "Severity-SHOULD" OR "Severity-MAY" | ||||||
Persona-Owner, # MULTIPLE VALUES: this can be "Persona-Owner" AND/OR "Persona-Contributor" | ||||||
Persona-Contributor, # MULTIPLE VALUES: this can be "Persona-Owner" AND/OR "Persona-Contributor" | ||||||
Lifecycle-BAU, # SINGLE VALUE: this can be "Lifecycle-Initial" OR "Lifecycle-BAU" OR "Lifecycle-EOL" | ||||||
Validation-TBD # SINGLE VALUE: this can be "Validation-Manual" OR "Validation-CI/Informational" OR "CI/Enforced" | ||||||
] | ||||||
priority: 11010 | ||||||
--- | ||||||
|
||||||
#### ID: BCPNFR21 - Category: User-defined types - Decorators | ||||||
|
||||||
Similar to [BCPNFR9](#id-bcpnfr9---category-inputs---decorators), User-defined types MUST implement certain [decorators](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/parameters#use-decorators), while they SHOULD others. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not very clear. I'd suggest to divide into 2 paragraphs, covering the MUST and the SHOULD part |
||||||
|
||||||
Decorators that MUST be implemented are `description` & `secure` (if sensitive). This is true for every property of the type, as well as the type itself. | ||||||
Decorators that SHOULD be implemented include but are not limited to `allowed`, `minValue`, `maxValue`, `minLength` & `maxLength` as they have a big impact on the module's usability. | ||||||
|
||||||
```bicep | ||||||
@desciption('My type''s description.') | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
type myType = { | ||||||
@description('Optional. The threshold of your resource.') | ||||||
@minValue(1) | ||||||
@maxValue(10) | ||||||
threshold: int? | ||||||
|
||||||
@description('Required. The SKU of your resource.') | ||||||
sku: ('Basic' | 'Premium' | 'Standard') | ||||||
} | ||||||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
--- | ||
title: BCPNFR9 - Inputs - Decorators | ||
url: /spec/BCPNFR9 | ||
geekdocNav: true | ||
geekdocAlign: left | ||
geekdocAnchor: true | ||
type: posts | ||
tags: [ | ||
Class-Resource, # MULTIPLE VALUES: this can be "Class-Resource" AND/OR "Class-Pattern" AND/OR "Class-Utility" | ||
Class-Pattern, # MULTIPLE VALUES: this can be "Class-Resource" AND/OR "Class-Pattern" AND/OR "Class-Utility" | ||
Type-NonFunctional, # SINGLE VALUE: this can be "Type-Functional" OR "Type-NonFunctional" | ||
Category-Inputs/Outputs, # SINGLE VALUE: this can be "Category-Testing" OR "Category-Telemetry" OR "Category-Contribution/Support" OR "Category-Documentation" OR "Category-CodeStyle" OR "Category-Naming/Composition" OR "Category-Inputs/Outputs" OR "Category-Release/Publishing" | ||
Language-Bicep, # MULTIPLE VALUES: this can be "Language-Bicep" AND/OR "Language-Terraform" | ||
Severity-MUST, # SINGLE VALUE: this can be "Severity-MUST" OR "Severity-SHOULD" OR "Severity-MAY" | ||
Persona-Owner, # MULTIPLE VALUES: this can be "Persona-Owner" AND/OR "Persona-Contributor" | ||
Persona-Contributor, # MULTIPLE VALUES: this can be "Persona-Owner" AND/OR "Persona-Contributor" | ||
Lifecycle-BAU, # SINGLE VALUE: this can be "Lifecycle-Initial" OR "Lifecycle-BAU" OR "Lifecycle-EOL" | ||
Validation-TBD # SINGLE VALUE: this can be "Validation-Manual" OR "Validation-CI/Informational" OR "CI/Enforced" | ||
] | ||
priority: 11010 | ||
--- | ||
|
||
#### ID: BCPNFR9 - Category: Inputs - Decorators | ||
|
||
Input parameters MUST make use of certain [decorators](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/parameters#use-decorators), while they SHOULD make use of others whenever possible. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment of the related for UDT |
||
|
||
Decorators that MUST always be implemented are `description` & `secure` (if sensitive). | ||
Decorators that SHOULD always be implemented include but are not limited to `allowed`, `minValue`, `maxValue`, `minLength` & `maxLength` as they have a big impact on the module's usability. | ||
|
||
```bicep | ||
@description('Optional. The threshold of your resource.') | ||
@minValue(1) | ||
@maxValue(10) | ||
param threshold: int? | ||
@description('Required. The SKU of your resource.') | ||
@allowed([ | ||
'Basic' | ||
'Premium' | ||
'Standard' | ||
]) | ||
param sku string | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Language-bicep tag looks commented out, please check