Skip to content

Commit 9411eae

Browse files
authored
Merge pull request #280943 from mumian/0716-specific-integer-type
Bicep - integer/string literal type and union type
2 parents f3d40f4 + fc99e9d commit 9411eae

File tree

3 files changed

+132
-29
lines changed

3 files changed

+132
-29
lines changed

articles/azure-resource-manager/bicep/data-types.md

Lines changed: 118 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Data types in Bicep
33
description: Describes the data types that are available in Bicep
44
ms.topic: reference
55
ms.custom: devx-track-bicep
6-
ms.date: 11/03/2023
6+
ms.date: 07/16/2024
77
---
88

99
# Data types in Bicep
@@ -39,7 +39,7 @@ var mixedArray = ['abc', 'def'
3939
'ghi']
4040
```
4141

42-
In an array, each item is represented by the [any type](bicep-functions-any.md). You can have an array where each item is the same data type, or an array that holds different data types.
42+
Each array element can be of any type. You can have an array where each item is the same data type, or an array that holds different data types.
4343

4444
The following example shows an array of integers and an array different types.
4545

@@ -58,7 +58,7 @@ var mixedArray = [
5858
]
5959
```
6060

61-
Arrays in Bicep are zero-based. In the following example, the expression `exampleArray[0]` evaluates to 1 and `exampleArray[2]` evaluates to 3. The index of the indexer may itself be another expression. The expression `exampleArray[index]` evaluates to 2. Integer indexers are only allowed on expression of array types.
61+
Arrays in Bicep are zero-based. In the following example, the expression `exampleArray[0]` evaluates to 1 and `exampleArray[2]` evaluates to 3. The index of the indexer can be another expression. The expression `exampleArray[index]` evaluates to 2. Integer indexers are only allowed on expression of array types.
6262

6363
```bicep
6464
var index = 1
@@ -102,7 +102,30 @@ When specifying integer values, don't use quotation marks.
102102
param exampleInt int = 1
103103
```
104104

105-
In Bicep, integers are 64-bit integers. When passed as inline parameters, the range of values may be limited by the SDK or command-line tool you use for deployment. For example, when using PowerShell to deploy a Bicep, integer types can range from -2147483648 to 2147483647. To avoid this limitation, specify large integer values in a [parameter file](parameter-files.md). Resource types apply their own limits for integer properties.
105+
Bicep integers are 64-bit integers. When passed as inline parameters, the range of values can be limited by the SDK or command-line tool you use for deployment. For example, when using PowerShell to deploy a Bicep, integer types can range from -2147483648 to 2147483647. To avoid this limitation, specify large integer values in a [parameter file](parameter-files.md). Resource types apply their own limits for integer properties.
106+
107+
Bicep supports integer literal type that refers to a specific value that is an exact integer. In the following example, _1_ is an integer literal type, _foo_ can only be assigned the value _1_ and no other value.
108+
109+
```bicep
110+
output foo 1 = 1
111+
```
112+
113+
An integer literal type can either be declared inline, as shown in the preceding example, or in a [`type` statement](./user-defined-data-types.md).
114+
115+
```bicep
116+
type oneType = 1
117+
118+
output foo oneType = 1
119+
output bar oneType = 2
120+
```
121+
122+
In the preceding example, assigning _2_ to _bar_ results in a [BCP033](./bicep-error-bcp033.md) error - _Expected a value of type "1" but the provided value is of type "2"_.
123+
124+
The following example shows using integer literal type with [union type](#union-types):
125+
126+
```bicep
127+
output bar 1 | 2 | 3 = 3
128+
```
106129

107130
Floating point, decimal or binary formats aren't currently supported.
108131

@@ -132,7 +155,7 @@ var test = {
132155
}
133156
```
134157

135-
In the preceding example, quotes are used when the object property keys contain special characters. For example space, '-', or '.'. The following example shows how to use interpolation in object property keys.
158+
In the preceding example, quotes are used when the object property keys contain special characters. For example space, '-', or '.'. The following example shows how to use interpolation in object property keys.
136159

137160
```bicep
138161
var stringVar = 'example value'
@@ -176,7 +199,7 @@ output accessorResult string = environmentSettings['dev'].name
176199

177200
[!INCLUDE [JSON object ordering](../../../includes/resource-manager-object-ordering-bicep.md)]
178201

179-
You will get the following error when accessing an nonexisting property of an object:
202+
You get the following error when accessing a nonexisting property of an object:
180203

181204
```error
182205
The language expression property 'foo' doesn't exist
@@ -196,7 +219,7 @@ output bar bool = contains(objectToTest, 'four') && objectToTest.four == 4
196219

197220
## Strings
198221

199-
In Bicep, strings are marked with singled quotes, and must be declared on a single line. All Unicode characters with code points between *0* and *10FFFF* are allowed.
222+
In Bicep, strings are marked with singled quotes, and must be declared on a single line. All Unicode characters with code points between _0_ and _10FFFF_ are allowed.
200223

201224
```bicep
202225
param exampleString string = 'test value'
@@ -211,21 +234,47 @@ The following table lists the set of reserved characters that must be escaped by
211234
| `\n` | line feed (LF) ||
212235
| `\r` | carriage return (CR) ||
213236
| `\t` | tab character ||
214-
| `\u{x}` | Unicode code point `x` | **x** represents a hexadecimal code point value between *0* and *10FFFF* (both inclusive). Leading zeros are allowed. Code points above *FFFF* are emitted as a surrogate pair.
237+
| `\u{x}` | Unicode code point `x` | **x** represents a hexadecimal code point value between _0_ and _10FFFF_ (both inclusive). Leading zeros are allowed. Code points above _FFFF_ are emitted as a surrogate pair. |
215238
| `\$` | `$` | Only escape when followed by `{`. |
216239

217240
```bicep
218241
// evaluates to "what's up?"
219242
var myVar = 'what\'s up?'
220243
```
221244

245+
Bicep supports string literal type that refers to a specific string value. In the following example, _red_ is a string literal type, _redColor_ can only be assigned the value _red_ and no other value.
246+
247+
```bicep
248+
output redColor 'red' = 'red'
249+
```
250+
251+
A string literal type can either be declared inline, as shown in the preceding example, or in a [`type` statement](./user-defined-data-types.md).
252+
253+
```bicep
254+
type redColor = 'red'
255+
256+
output colorRed redColor = 'red'
257+
output colorBlue redColor = 'blue'
258+
```
259+
260+
In the preceding example, assigning _blue_ to _colorBlue_ results in a [BCP033](./bicep-error-bcp033.md) error - _Expected a value of type "'red'" but the provided value is of type "'blue'"_.
261+
262+
The following example shows using string literal type with [union type](#union-types):
263+
264+
```bicep
265+
type direction = 'north' | 'south' | 'east' | 'west'
266+
267+
output west direction = 'west'
268+
output northWest direction = 'northwest'
269+
```
270+
222271
All strings in Bicep support interpolation. To inject an expression, surround it by `${` and `}`. Expressions that are referenced can't span multiple lines.
223272

224273
```bicep
225274
var storageName = 'storage${uniqueString(resourceGroup().id)}'
226275
```
227276

228-
## Multi-line strings
277+
### Multi-line strings
229278

230279
In Bicep, multi-line strings are defined between three single quote characters (`'''`) followed optionally by a newline (the opening sequence), and three single quote characters (`'''` - the closing sequence). Characters that are entered between the opening and closing sequence are read verbatim, and no escaping is necessary or possible.
231280

@@ -268,6 +317,66 @@ var myVar6 = '''interpolation
268317
is ${blocked}'''
269318
```
270319

320+
## Union types
321+
322+
In Bicep, a union type allows the creation of a combined type consisting of a set of sub-types. An assignment is valid if any of the individual sub-type assignments are permitted. The `|` character separates individual sub-types using an _or_ condition. For example, the syntax _'a' | 'b'_ means that a valid assignment could be either _'a'_ or _'b'_. Union types are translated into the [allowed-value](../templates/definitions.md#allowed-values) constraint in Bicep, so only literals are permitted as members. Unions can include any number of literal-typed expressions.
323+
324+
```bicep
325+
type color = 'Red' | 'Blue' | 'White'
326+
type trueOrFalse = 'true' | 'false'
327+
type permittedIntegers = 1 | 2 | 3
328+
type oneOfSeveralObjects = {foo: 'bar'} | {fizz: 'buzz'} | {snap: 'crackle'}
329+
type mixedTypeArray = ('fizz' | 42 | {an: 'object'} | null)[]
330+
```
331+
332+
Any type expression can be used as a sub-type in a union type declaration (between `|` characters). For example, the following examples are all valid:
333+
334+
```bicep
335+
type foo = 1 | 2
336+
type bar = foo | 3
337+
type baz = bar | (4 | 5) | 6
338+
```
339+
340+
### Custom-tagged union data type
341+
342+
Bicep supports custom tagged union data type, which is used to represent a value that can be one of several different types. To declare a custom tagged union data type, you can use a `@discriminator()` decorator. [Bicep CLI version 0.21.X or higher](./install.md) is required to use this decorator. The syntax is:
343+
344+
```bicep
345+
@discriminator('<property-name>')
346+
```
347+
348+
The discriminator decorator takes a single parameter, which represents a shared property name among all union members. This property name must be a required string literal on all members and is case-sensitive. The values of the discriminated property on the union members must be unique in a case-insensitive manner.
349+
350+
```bicep
351+
type FooConfig = {
352+
type: 'foo'
353+
value: int
354+
}
355+
356+
type BarConfig = {
357+
type: 'bar'
358+
value: bool
359+
}
360+
361+
@discriminator('type')
362+
param ServiceConfig FooConfig | BarConfig | { type: 'baz', *: string } = { type: 'bar', value: true }
363+
```
364+
365+
The parameter value is validated based on the discriminated property value. For instance, in the preceding example, if the _serviceConfig_ parameter is of type _foo_, it's validated using the _FooConfig_ type. Similarly, if the parameter is of type _bar_, it's validated using the _BarConfig_ type. This pattern applies to other types as well.
366+
367+
There are some limitations with union type.
368+
369+
* Union types must be reducible to a single Azure Resource Manager (ARM) type. The following definition is invalid:
370+
371+
```bicep
372+
type foo = 'a' | 1
373+
```
374+
375+
* Only literals are permitted as members.
376+
* All literals must be of the same primitive data type (e.g., all strings or all integers).
377+
378+
The union type syntax can be used in [user-defined data types](./user-defined-data-types.md).
379+
271380
## Secure strings and objects
272381

273382
Secure string uses the same format as string, and secure object uses the same format as object. With Bicep, you add the `@secure()` [decorator](./parameters.md#decorators) to a string or object.

articles/azure-resource-manager/bicep/parameters.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Resource Manager resolves parameter values before starting the deployment operat
1414

1515
Each parameter must be set to one of the [data types](data-types.md).
1616

17-
You're limited to 256 parameters in a Bicep file. For more information, see [Template limits](../templates/best-practices.md#template-limits).
17+
Bicep allows a maximum of 256 parameters. For more information, see [Template limits](../templates/best-practices.md#template-limits).
1818

1919
For parameter best practices, see [Parameters](./best-practices.md#parameters).
2020

@@ -59,7 +59,7 @@ param storageAccountConfig {
5959
}
6060
```
6161

62-
For more information, see [User-defined data types](./user-defined-data-types.md#user-defined-data-type-syntax).
62+
For more information, see [User-defined data types](./user-defined-data-types.md#syntax).
6363

6464
## Default value
6565

@@ -105,7 +105,7 @@ The following table describes the available decorators and how to use them.
105105

106106
| Decorator | Apply to | Argument | Description |
107107
| --------- | ---- | ----------- | ------- |
108-
| [allowed](#allowed-values) | all | array | Allowed values for the parameter. Use this decorator to make sure the user provides correct values. |
108+
| [allowed](#allowed-values) | all | array | Use this decorator to make sure the user provides correct values. This decorator is only permitted on `param` statements. To declare that a property must be one of a set of predefined values in a [`type`](./user-defined-data-types.md) or [`output`](./outputs.md) statement, use [union type syntax](./data-types.md#union-types). Union type syntax can also be used in `param` statements.|
109109
| [description](#description) | all | string | Text that explains how to use the parameter. The description is displayed to users through the portal. |
110110
| [maxLength](#length-constraints) | array, string | int | The maximum length for string and array parameters. The value is inclusive. |
111111
| [maxValue](#integer-constraints) | int | int | The maximum value for the integer parameter. This value is inclusive. |
@@ -203,7 +203,7 @@ When you hover your cursor over **storageAccountName** in VS Code, you see the f
203203

204204
:::image type="content" source="./media/parameters/vscode-bicep-extension-description-decorator-markdown.png" alt-text="Use Markdown-formatted text in VSCode":::
205205

206-
Make sure the text follows proper Markdown formatting; otherwise, it may not display correctly when rendered
206+
Make sure the text follows proper Markdown formatting; otherwise, it may not display correctly when rendered.
207207

208208
### Metadata
209209

@@ -220,7 +220,7 @@ You might use this decorator to track information about the parameter that doesn
220220
param settings object
221221
```
222222

223-
When you provide a `@metadata()` decorator with a property that conflicts with another decorator, that decorator always takes precedence over anything in the `@metadata()` decorator. So, the conflicting property within the @metadata() value is redundant and will be replaced. For more information, see [No conflicting metadata](./linter-rule-no-conflicting-metadata.md).
223+
When you provide a `@metadata()` decorator with a property that conflicts with another decorator, that decorator always takes precedence over anything in the `@metadata()` decorator. So, the conflicting property within the `@metadata()` value is redundant and will be replaced. For more information, see [No conflicting metadata](./linter-rule-no-conflicting-metadata.md).
224224

225225
## Use parameter
226226

articles/azure-resource-manager/bicep/user-defined-data-types.md

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,15 @@ Learn how to use user-defined data types in Bicep. For system-defined data types
1212

1313
[Bicep CLI version 0.12.X or higher](./install.md) is required to use this feature.
1414

15-
## User-defined data type syntax
15+
## Syntax
1616

1717
You can use the `type` statement to define user-defined data types. In addition, you can also use type expressions in some places to define custom types.
1818

1919
```bicep
2020
type <user-defined-data-type-name> = <type-expression>
2121
```
2222

23-
> [!NOTE]
24-
> The [`@allowed` decorator](./parameters.md#decorators) is only permitted on [`param` statements](./parameters.md). To declare that a property must be one of a set of predefined values in a `type` or [`output`](./outputs.md) statement, use union type syntax. Union type syntax may also be used in [`param` statements](./parameters.md).
23+
The [`@allowed`](./parameters.md#decorators) decorator is only permitted on [`param` statements](./parameters.md). To declare that a property with a set of predefined values in a `type`, use [union type syntax](./data-types.md#union-types).
2524

2625
The valid type expressions include:
2726

@@ -95,13 +94,16 @@ The valid type expressions include:
9594
}
9695
```
9796
98-
The following sample shows how to use the union type syntax to list a set of predefined values:
97+
The following sample shows how to use the [union type syntax](./data-types.md#union-types) to list a set of predefined values:
9998
10099
```bicep
100+
type directions = 'east' | 'south' | 'west' | 'north'
101+
101102
type obj = {
102103
level: 'bronze' | 'silver' | 'gold'
103104
}
104105
```
106+
105107
**Recursion**
106108
107109
Object types may use direct or indirect recursion so long as at least leg of the path to the recursion point is optional. For example, the `myObjectType` definition in the following example is valid because the directly recursive `recursiveProp` property is optional:
@@ -225,17 +227,9 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' = {
225227
}
226228
```
227229

228-
## Declare tagged union type
229-
230-
To declare a custom tagged union data type within a Bicep file, you can place a discriminator decorator above a user-defined type declaration. [Bicep CLI version 0.21.X or higher](./install.md) is required to use this decorator. The syntax is:
231-
232-
```bicep
233-
@discriminator('<propertyName>')
234-
```
235-
236-
The discriminator decorator takes a single parameter, which represents a shared property name among all union members. This property name must be a required string literal on all members and is case-sensitive. The values of the discriminated property on the union members must be unique in a case-insensitive manner.
230+
## Tagged union data type
237231

238-
The following example shows how to declare a tagged union type:
232+
To declare a custom tagged union data type within a Bicep file, you can place a discriminator decorator above a user-defined type declaration. [Bicep CLI version 0.21.X or higher](./install.md) is required to use this decorator. The following example shows how to declare a tagged union data type:
239233

240234
```bicep
241235
type FooConfig = {
@@ -256,7 +250,7 @@ param serviceConfig ServiceConfig = { type: 'bar', value: true }
256250
output config object = serviceConfig
257251
```
258252

259-
The parameter value is validated based on the discriminated property value. In the preceding example, if the *serviceConfig* parameter value is of type *foo*, it undergoes validation using the *FooConfig*type. Likewise, if the parameter value is of type *bar*, validation is performed using the *BarConfig* type, and this pattern continues for other types as well.
253+
For more information, see [Custom tagged union data type](./data-types.md#custom-tagged-union-data-type).
260254

261255
## Import types between Bicep files
262256

0 commit comments

Comments
 (0)