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

new any() doc, updates to arm2bicep doc, example cleanup #936

Merged
merged 4 commits into from
Nov 17, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/arm2bicep.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,10 @@ Get a property (`resourceProperty`) from a created resource (assumes `resource`
Conditionally declare a property value | `if(parameters('isMonday'), 'valueIfTrue', 'valueIfFalse')` | `isMonday ? 'valueIfTrue' | 'valueIfFalse'` ([spec](https://github.com/Azure/bicep/blob/main/docs/spec/expressions.md#ternary-operator))
Separate a solution into multiple files | Use [linked templates](https://docs.microsoft.com/azure/azure-resource-manager/templates/linked-templates#linked-template) | Use [modules](https://github.com/Azure/bicep/blob/main/docs/spec/modules.md)
Set the target scope of the deployment to a subscription | `"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#"` | `targetScope = 'subscription'` ([spec](https://github.com/Azure/bicep/blob/main/docs/spec/resource-scopes.md#declaring-the-target-scopes))
Set a dependency between two resources | `"dependsOn": ["[resourceId('Microsoft.Storage/storageAccounts', 'parameters('storageAcountName'))]"`] | Either dependsOn not needed because of [auto-dependency management](https://github.com/Azure/bicep/blob/main/docs/spec/resources.md#implicit-dependency) or manually set dependsOn with `dependsOn: [ stg ]` ([spec](https://github.com/Azure/bicep/blob/main/docs/spec/resources.md#resource-dependencies))

## Incorporating new syntax into best practices

* Avoid the `reference()` and `resourceId()` functions like the plague. Anytime the resource you are referencing is declared in the same bicep project, you can pull the equivalent information from the resource identifier in bicep (i.e. `stg.id` or `stg.properties.primaryEndpoints.blob`). This also creates an [**implicit dependency**](https://github.com/Azure/bicep/blob/main/docs/spec/resources.md#implicit-dependency) between resources, which means you can eliminate your usage of the `dependsOn` property. All of this results in cleaner, more maintainable code.
* Use consistent casing for identifiers. When in doubt, use [camel case](https://en.wikipedia.org/wiki/Camel_case) (e.g. `param myCamelCasedParameter string`)
* If you are going to add a `description` to a parameter, ensure the parameter is in fact descriptive. If you have a `location` parameter, having a description of "the resource's location" is not particularly helpful and results in your code being noisier. Sometimes a `//` comment is more appropriate.
10 changes: 5 additions & 5 deletions docs/examples/101/function-app-create/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -129,19 +129,19 @@ resource functionApp 'Microsoft.Web/sites@2020-06-01' = {
appSettings: [
{
name: 'AzureWebJobsStorage'
value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageAccount.id, '2019-06-01').keys[0].value}'
value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageAccount.id, storageAccount.apiVersion).keys[0].value}'
}
{
name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING'
value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageAccount.id, '2019-06-01').keys[0].value}'
value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageAccount.id, storageAccount.apiVersion).keys[0].value}'
}
{
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
value: '${reference(appInsights.id, '2018-05-01-preview').InstrumentationKey}'
value: appInsights.properties.InstrumentationKey
}
{
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
value: 'InstrumentationKey=${reference(appInsights.id, '2018-05-01-preview').InstrumentationKey}'
value: 'InstrumentationKey=${appInsights.properties.InstrumentationKey}'
}
{
name: 'FUNCTIONS_WORKER_RUNTIME'
Expand Down Expand Up @@ -246,7 +246,7 @@ resource functionAppConfig 'Microsoft.Web/sites/config@2020-06-01' = {
resource functionAppBinding 'Microsoft.Web/sites/hostNameBindings@2020-06-01' = {
name: '${functionApp.name}/${functionApp.name}.azurewebsites.net'
properties: {
siteName: functionAppName
siteName: functionApp.name
hostNameType: 'Verified'
}
}
4 changes: 2 additions & 2 deletions docs/examples/101/function-app-create/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,11 @@
},
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('Microsoft.Insights/components', variables('appInsightsName')), '2018-05-01-preview').InstrumentationKey]"
"value": "[reference(resourceId('Microsoft.Insights/components', variables('appInsightsName'))).InstrumentationKey]"
},
{
"name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
"value": "[format('InstrumentationKey={0}', reference(resourceId('Microsoft.Insights/components', variables('appInsightsName')), '2018-05-01-preview').InstrumentationKey)]"
"value": "[format('InstrumentationKey={0}', reference(resourceId('Microsoft.Insights/components', variables('appInsightsName'))).InstrumentationKey)]"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
Expand Down
70 changes: 70 additions & 0 deletions docs/the-any-function.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# When and how to use the any() function

Bicep supports a special function called `any()` to resolve type errors in the bicep type system. For a number of reasons, the type system may throw a false-positive error or warning. These are cases where bicep is telling you something is wrong, even though it is correct. These cases typically come from two cases:

* There is a genuine bug in the bicep type system
* The resource type that is being declared has an incorrect api definition (swagger spec). For example, their API definition may expect a value to be an int, even though the actual running API is expecting a string.

When either of the above occurs you can use the `any()` function to suppress the error.

To help us out, it would also be great if you can file a relevant issue on which false-positive you encountered. For missing or incorrect type info, you can add your details to the pinned issue we have tracking it ([missing type validation/inaccuracies](https://github.com/Azure/bicep/issues/784)).

> **Note:** This function does not actually exist in the ARM Template runtime, it is only used by the bicep language and not emitted in the built template JSON.

## How to use the any() function

In the following example, at the time of this writing, the API definition for Azure Container Instances is incorrect because the `properties.containers[*].properties.resources.requests.cpu` and `properties.containers[*].properties.resources.requests.memoryInGB` properties expect an `int`, but actually require a number, since the expected values can be non-integer values (i.e. `0.5`). Since number types are not valid in bicep (or ARM templates) we are forced to pass the numbers as strings. As a result, if I use the below code in my bicep file, I will get warnings on those properties.
alex-frankel marked this conversation as resolved.
Show resolved Hide resolved

You can see this example live in the [bicep playground](https://aka.ms/bicepdemo#eJyNVFtvmzAUfudX+I32IUDSbV2RNi1dtq5S17ISdQ/TVDnGSSzhS3wJjab899kQE0IUtfCAOed8F1vHR0AJKVCaS7jAY4S4YfoeUmxDkrAF+AQMIyuD8/r3TGLFjUT4RnIjzs4jUpwHoqEgGh8Cj0mDXS3d5Ksyg0pVXBYe8C8AQGFkJE6BlgYHW19ecgQ14WxP3bfhK4Ig8ClQiTEiIKQESa74XEeIMw0Jw/KWKQ0ZwnEbqXnUl1EyvBoMR4NkGFoRZ4hZ1ykInU9hmdWghZAdSWirvHzarmxQSC6w1ASrtKYCoMXayJ86AnYZ9/SlwjZzzNQ8hNrj7ULSd9HVAAqIljjs1AkudUeyL9yKaI54afmmX7Own7UUKfiYHIS3nb+/nTVmayI5o5jpJygJnJX4Vfnd7n8/PE6yx295/jy5fv7xkE/7RtawNK5wOLqMEvsO04uL5EN40tfblLJxnrtAX63px6dG87Br4xigJWQLXAC9JArMJacgrO3Z5vkMwg72tL3usa15aSj+6S7Lq8dFXVUG9dLuJF5DGVdVFS81Lfs76HfVnJRvtOMvUq/pXMLOA6WP4rbBhbFaSfS+74JiyuXmlt1c1/nL0w72a79qvo0zIsZFUXd6q33U3F1Tp5v6qKG9nD8CvRHu4DIzKwnyyIIpN8fu4AxbTj/ygj2eq2mDuyPMvDjY1s0xbrQwugZ8/zW53w+yekhF+wsetTuM5quC/Qf9MoIp)

```
resource wpAci 'microsoft.containerInstance/containerGroups@2019-12-01' = {
name: 'wordpress-containerinstance'
location: location
properties: {
containers: [
{
name: 'wordpress'
properties: {
...
resources: {
requests: {
cpu: '0.5'
memoryInGB: '0.7'
}
}
}
}
]
}
}
```

In order to get rid of these warnings, simply wrap the relevant property value(s) in the any function like so:

```
resource wpAci 'microsoft.containerInstance/containerGroups@2019-12-01' = {
name: 'wordpress-containerinstance'
location: location
properties: {
containers: [
{
name: 'wordpress'
properties: {
...
resources: {
requests: {
cpu: any('0.5')
memoryInGB: any('0.7')
}
}
}
}
]
}
}
```

You can see in the live code in [the playground](https://aka.ms/bicepdemo#eJyNVFtv2jAUfs+v8JvhgSTQbV0jbRodW1epa7MGdQ/TVBnHgKXENr5A0cR/n53gEIJQmzzEOT7fxUfHRyCJSqA0l2hBxhhzw/Q9KokNScoW4BMwjK4MyarfniSKG4nJjeRG9PohzfuBqCmoJsfAU9Jgn1tus1WRIqU2XOYe8C8AQBFsJEmAloYEO59ecIw05exA3bXhM4Ig8FtgI8aYAlhSLLnicx1izjSijMhbpjRimERNpOJRX0bx8GowHA3iIbQizhCzrhMAnU9hmdWggdA9CbRZXj5pVjYoJBdEakpUUlEB0GBt5E8VAfsd93SlYLNzylQ/tLTlbUOSd+HVAAmElwS28gSXuiXZFW5ENMe8sHzTryns7lqKBHyMj8K71t/f1pqwNZWclYTpJyQpmhXkVfn96X8/PE7Sx29Z9jy5fv7xkE27RtaoMC5xOLoMY/sOk4uL+AM86+ttSuk4y1ygq1b341Otedy1UQTwErEFyYFeUgXmkpcAVvZs83wGsIU9b69dtjUvTEl+usvyarlKl5UivbQnidZIRpvNJlrqsuieoNtVc1q80Y6/SJ2mcxt2Hih9ErcNLkwCENv2YBy+h/2uZ1Jyub1lN9dN0mUnqe3lsPar+lt7pGKc51XPNy5O2rxt73x7n7S2l/PF0FvhSpiaWUGxR+ZMuYl2h2bEcvrhFxzwXE1r3B1l5sXBdm6icaOF0RXg+6/J/WGkVeMqPFz1sDlhOF/l7D8GbIVb), the warnings go away.

`any()` works on any assigned value in bicep. You can see a more complex use of `any()` in the `nested-vms-in-virtual-network` example on [line 31](https://github.com/Azure/bicep/blob/main/docs/examples/301/nested-vms-in-virtual-network/nic.bicep#L31) of `nic.bicep` in which the use of `any()` wraps the entire ternary expression as an argument.