Azure / Azure/bicep

Set or skip an object property based on a condition

Open
#15,451 8 comments 6 reactions 0 assignees View on GitHub
enhancement
Dominant language
Bicep
Stars
3.6k
Forks
830
Avg merge
1d 2h
Merged PRs (30d)
79

Description

## Problem statement
This issue exists generally to track the requirement of being able to conditionally set a property on an object. This is often necessary, because although when authoring in Bicep we don't distinguish between the absence of a value and explicitly setting a value to `null`, some of the services which handle resource deployment (resource providers) do.

For example, it might be desirable to conditionally not set a property:
```bicep
param setFooProp bool

resource foo '' = {
name: 'foo'
properties: {
fooProp: setFooProp ? 'bar' : null
barProp: 'baz'
}
}
```

However, if `setFooProp` is false, this is equivalent to writing:
```bicep
resource foo '' = {
name: 'foo'
properties: {
fooProp: null
barProp: 'baz'
}
}
```

Whereas the author may instead intend to have the following instead:
```bicep
resource foo '' = {
name: 'foo'
properties: {
barProp: 'baz'
}
}
```

To accomplish the latter option, a more significant refactor is needed. We support this with the spread operator:
```bicep
resource foo '' = {
name: 'foo'
properties: {
...(setFooProp ? { fooProp: 'bar' } : {})
barProp: 'baz'
}
}
```

Or by refactoring into a variable:
```bicep
var fooProps = setFooProp ? {
fooProp: 'bar'
} : {}

resource foo '' = {
name: 'foo'
properties: {
...fooProps
barProp: 'baz'
}
}
```

## Why is this a new issue?
The requirement for "set-or-skip" was originally being tracked by #387, which is now over 4 years old, and is one of our highest-upvoted issue with many comments. Since then, we've implemented the spread operator ([usage docs](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/operator-spread)).

The requirements of the original issue are satisfied with the spread operator, but we wanted to continue to collect feedback about set-or-skip, because of the popularity of the thread. We are having a hard time prioritizing this work because we're not sure whether:
* This is still important to people (we can't tell whether the upvotes on the issue were before or after spread was released!)
* The spread operator is too complex to use
* The spread operator isn't well known or difficult to discover (are there docs improvements to be made?)
* The spread operator has feature gaps
* ...something else?

As such we have closed #387 but intend to keep this issue open to track new feedback. Please comment on this issue if you'd like to help us answer the above!

## Special-case syntax
Under #387, the original discussion was mostly around introducing a new dedicated syntax - here is a prototype of the syntax example for "set-or-skip" syntax that was being discussed. This is not implemented, and is not something we are currently considering without clear feedback supporting it:

```bicep
var obj = {
propNormal: value
if (condition) {
propConditional1: propConditional1Value
propConditional2: propConditional2Value
}
}

var arr = [
element
if (condition) { condElement1, condElement2 }
]
```

Contributor guide

Open the contributing guide

Research direction

Review the existing spread operator usage and the linked operator-spread documentation, then compare the requested behavior with the discussion in #387. Treat this issue as feedback gathering rather than an implementation task; no files, tests, concrete scope, or completion criteria are defined.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.