Skip to content

Remove onlyIfNotExists experimental feature#17996

Merged
tsmallig33 merged 4 commits into
mainfrom
tasmalligan/OnlyIfNotExistsGA
Sep 18, 2025
Merged

Remove onlyIfNotExists experimental feature#17996
tsmallig33 merged 4 commits into
mainfrom
tasmalligan/OnlyIfNotExistsGA

Conversation

@tsmallig33
Copy link
Copy Markdown
Member

@tsmallig33 tsmallig33 commented Sep 10, 2025

Description

Remove onlyIfNotExists experimental feature to make decorator GA.

Updated EmitterSettings.cs to emit template language 2.0 when onlyIfNotExists() decorator is used.

Checklist

Microsoft Reviewers: Open in CodeFlow

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Sep 10, 2025

Test this change out locally with the following install scripts (Action run 17833942159)

VSCode
  • Mac/Linux
    bash <(curl -Ls https://aka.ms/bicep/nightly-vsix.sh) --run-id 17833942159
  • Windows
    iex "& { $(irm https://aka.ms/bicep/nightly-vsix.ps1) } -RunId 17833942159"
Azure CLI
  • Mac/Linux
    bash <(curl -Ls https://aka.ms/bicep/nightly-cli.sh) --run-id 17833942159
  • Windows
    iex "& { $(irm https://aka.ms/bicep/nightly-cli.ps1) } -RunId 17833942159"

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Sep 10, 2025

Dotnet Test Results

    90 files   -     45      90 suites   - 45   38m 25s ⏱️ - 24m 17s
12 348 tests  -     14  12 348 ✅  -     14  0 💤 ±0  0 ❌ ±0 
28 441 runs   - 14 217  28 441 ✅  - 14 217  0 💤 ±0  0 ❌ ±0 

Results for commit a2ba350. ± Comparison against base commit e350617.

This pull request removes 1921 and adds 652 tests. Note that renamed tests count towards both.

		nestedProp1: 1
		nestedProp2: 2
		prop1: true
		prop2: false
	1
	2
	\$'")
	prop1: true
	prop2: false
…
Bicep.Core.IntegrationTests.AzTypesViaRegistryTests ‑ Bicep_compiler_handles_corrupted_extension_package_gracefully (\u001f�\u0008\u0000\u0000\u0000\u0000\u0000\u0000
�ӽ
�0\u0010\u0007��>E�\u0001❽$���Ep�\u0001b{�bki+\u0014�w7\u000e����\u0017�ߘ;���_M����˹n�%m&J�\u001ax����\u0006�
�w �j�e��Iz����~�O�����t���\u0014���@\u0016P%�I�8�l����\�MweΝ�7���^\u000c���������oE��\u000f\u0011	�`"@�H\u000b0����#������xUrWq�r��b��x&7����۳\u0005A\u0010\u0004�s\u0005v\u0018R�\u0000\u000c\u0000\u0000,"Value cannot be null. (Parameter 'source')")
Bicep.Core.IntegrationTests.AzTypesViaRegistryTests ‑ Bicep_compiler_handles_corrupted_extension_package_gracefully (\u001f�\u0008\u0000\u0000\u0000\u0000\u0000\u0000
�ӽ\u000e�0\u0010\u0007��>E��ܕ��\u0003����(�\u001f�\u0018(������\u0001�`b�c/�^���do�]a�E�\u0008R�$��
\u0002����\u000052�\u0017`@Z\u0013c��}�\u0011m�m\u001dFY�\u001f$3n��,r$�IPfKBf&5D�P;L֐߬?孻��s��Tnh(�\u001a�~h4������O�\u0007�\u000c5�\u0014\u0010U�!�(C\u001e�"�����\u001fkO\u0010EQ\u0014��	\u001b
\u001b\u001e\u0000\u000c\u0000\u0000,"The path: index.json was not found in artifact contents")
Bicep.Core.IntegrationTests.AzTypesViaRegistryTests ‑ Bicep_compiler_handles_corrupted_extension_package_gracefully (\u001f�\u0008\u0000\u0000\u0000\u0000\u0000\u0000
��M\u000b�0\u0018\u0007��\u0014�\u0007�{�^2�\u0010t�\u0008\u000b��1r��\u0016j �囇�t�%h������������Z%�(�d\x\u0018��\u0018����\u00060�@�\u0011D$\u0017�ک{�ţ�TaZ\u0019c�\u001fD玪�L� ��\u0012&\u0002��O�R13s�9\u0008���.a�'����7�YW��۴:|�o�#���B\u0019\u0002N�y+�|@Dp���(����?�(>.���9�bw�\u001fx�,˲��\u0000�\u0011��\u0000\u000c\u0000\u0000,"'7' is an invalid end of a number. Expected a delimiter. Path: $.INVALID_JSON | LineNumber: 0 | BytePositionInLine: 20.")
Bicep.Core.IntegrationTests.AzTypesViaRegistryTests ‑ Bicep_compiler_handles_corrupted_extension_package_gracefully (\u001f�\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0003�Խ
�0\u0010\u0007��>E�\u0003����
\u001d\u0004\u0007+R\u0005�U�
X�U�
\u0005_�t\u0010�\u0016�~\u0008�7&\u0007w����{U��JtQ\u0012�\u0002p	�\u001b\u0018�\u0010��
*|D�7@�Ki�q��$-\u001ee�
3�\u0018�~\u0010�cU��\u000e�/�\u000c����\u001d\u0000�`f��]w4�wU]�4OtM��-oʳ��iu��o�\u001e��\u000fL *��@)0�����\u0011���?��Ӊ��r\u001b�N��.v\u0016���S�dY�e
�\u0005gwA
\u0000\u000c\u0000\u0000,"'7' is an invalid end of a number. Expected a delimiter. Path: $.INVALID_JSON | LineNumber: 0 | BytePositionInLine: 20.")
Bicep.Core.IntegrationTests.AzTypesViaRegistryTests ‑ Bicep_compiler_handles_corrupted_extension_package_gracefully (\u001f�\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0003��K\u000e�0\u0010\u0006�=EOPf�)�\u0005{�^�Q\u0012\u001f�\u0018\u001e��xw���\u0005�
�����Nf��W�����\u001e�V1m!Rbn�%̣�\u0003�(м�\u0000��\u0008!��7\u0019�֍��*K��A�Jۜ�<C�S\u0002昕a$N���\u000e�5�7ۜ��]]�9u�K74\u0014S
k?4\u0018���ߚ�)�\u0000$PC\u0012\u0003"\u0010��#��r�L�y�7\u0008� \u0008��\u0004j�^\u001e\u0000\u000c\u0000\u0000,"The path: index.json was not found in artifact contents")
Bicep.Core.IntegrationTests.AzTypesViaRegistryTests ‑ Bicep_compiler_handles_corrupted_extension_package_gracefully (\u001f�\u0008\u0000\u0000\u0000\u0000\u0000\u0000\u0003���
�@\u0010\u0007�=�\u0014�\u000f��~�\u001ax�\u0012t�\u00016��H\u00135\u0010�wo=D\u0017��e���;\u00033��g˭��h3�\u001b&E\u000cKF�\u0006N���{�+C�y\u0002\u0002Fk�M��7\u0019pmZ[�U�1�\u0007���6/0�FG\u0002����(6Qh\u0016����xL+�\u001e��̰c��R���X����F����\u0019��\u000fR\u0011�!��9\u0008A Ԓ���%����\u001b
v%v\u0015�-f\u001b,�X\u0007+z��\u0006�s��y��}�\u0003L\u0005@\u000f\u0000\u000c\u0000\u0000,"Value cannot be null. (Parameter 'source')")
Bicep.Core.IntegrationTests.DirectResourceCollectionTests ‑ DirectResourceCollectionAccess_NotAllowedWithinLoops ("output loopOutput array = [for i in range(0, 2): {
  prop: map(containerWorkers, (w) => w.properties.ipAddress.ip)
}]")
Bicep.Core.IntegrationTests.DirectResourceCollectionTests ‑ DirectResourceCollectionAccess_NotAllowedWithinLoops ("resource propertyLoop 'Microsoft.ContainerInstance/containerGroups@2022-09-01' = {
  name: 'gh9440-loop'
  location: 'westus'
  properties: {
    containers: [for i in range(0, 2): {
      name: 'gh9440-w1c-${i}'
      properties: {
        command: [
          'echo "${join(map(containerWorkers, (w) => w.properties.ipAddress.ip), ',')}"'
        ]
      }
    }]
  }
}")
Bicep.Core.IntegrationTests.DirectResourceCollectionTests ‑ DirectResourceCollectionAccess_NotAllowedWithinLoops ("var loopVar = [for i in range(0, 2): {
  prop: map(containerWorkers, (w) => w.properties.ipAddress.ip)
}]")
Bicep.Core.IntegrationTests.Emit.ParamsFileWriterTests ‑ Params_file_with_no_errors_should_compile_correctly ("
using 'main.bicep'

// involves all syntax
param myParam = {
  arr: [
    {
      a : 'b'
    }
    {
      c : true
    }
  ]
  name: 'complex object!'
  priority: 3
  val: null
  obj: {
      a: 'b'
      c: [
          'd'
           1
      ]
  }
}","
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "myParam": {
      "value": {
        "arr" : [
          {
            "a" : "b"
          },
          {
            "c" : true
          }
        ],
        "name" : "complex object!",
        "priority" : 3,
        "val" : null,
        "obj" : {
          "a" : "b",
          "c" : [
            "d",
            1
          ]
        }
      }
    }
  }
}","
param myParam object
")
…

♻️ This comment has been updated with latest results.

@tsmallig33 tsmallig33 marked this pull request as ready for review September 10, 2025 16:41
@tsmallig33 tsmallig33 marked this pull request as draft September 10, 2025 16:43
@tsmallig33 tsmallig33 marked this pull request as ready for review September 18, 2025 14:18
@tsmallig33 tsmallig33 merged commit bc5e0bf into main Sep 18, 2025
42 checks passed
@tsmallig33 tsmallig33 deleted the tasmalligan/OnlyIfNotExistsGA branch September 18, 2025 15:39
@nnellans
Copy link
Copy Markdown

nnellans commented Oct 4, 2025

Is there any docs on onlyIfNotExists? I can't seem to find any (sorry if I missed it).

@jcbartle
Copy link
Copy Markdown

jcbartle commented Oct 6, 2025

@tsmallig33 / @anthony-c-martin - I've started getting the following error when trying to use the onlyIfNotExists decorator:

Status Message: Deployment template validation failed: 'Template language version '2.0' does not support feature 'OnlyIfNotExists'.'. (Code:InvalidTemplate)

This occurs whether or not the following is present in my bicepconfig.json file:

"experimentalFeaturesEnabled": {
  "onlyIfNotExists": true
}

I'm running Bicep CLI version 0.38.5.

Any thoughts? This decorator is extremely useful for role assignments and Key Vault secrets.

@tsmallig33
Copy link
Copy Markdown
Member Author

@tsmallig33 / @anthony-c-martin - I've started getting the following error when trying to use the onlyIfNotExists decorator:

Status Message: Deployment template validation failed: 'Template language version '2.0' does not support feature 'OnlyIfNotExists'.'. (Code:InvalidTemplate)

This occurs whether or not the following is present in my bicepconfig.json file:

"experimentalFeaturesEnabled": {
  "onlyIfNotExists": true
}

I'm running Bicep CLI version 0.38.5.

Any thoughts? This decorator is extremely useful for role assignments and Key Vault secrets.

@jcbartle Do you have a correlationId that you could share for the issue?

@jcbartle
Copy link
Copy Markdown

jcbartle commented Oct 6, 2025

Hi, @tsmallig33, and thank you for the quick response! Here's a correlation ID from one of the failed deployments which contained this error message:

05881dbb-a8d4-48b6-8173-60f51263672c

Some good news. I actually just removed that decorator from my role assignment modules, and that obviously fixed the error I posted about above, but the code is no longer throwing the old RoleAssignmentAlreadyExists error we always used to get. Did the MS team finally fix the Bicep bug which erroneously threw that error? It seems like that may be the case (and that would be awesome).

Of course, I still need to use this decorator for Key Vault secrets, so figuring out the error above will still be useful.

Best,
J.C.

@tsmallig33
Copy link
Copy Markdown
Member Author

Hi @jcbartle, thank you for sharing. I don't see the InvalidDeployment error code mentioned in the logs for that correlationId - can you confirm the correlationId and location/environment where you are seeing the issue?

@jcbartle
Copy link
Copy Markdown

jcbartle commented Oct 7, 2025

Good morning, @tsmallig33. Here's a different correlation ID with the same errors:

05881dbb-a8d4-48b6-8173-60f51263672c

This is in Azure Government.

FYI, it appears that the RoleAssignmentExists error is still getting thrown - at least some of the time - in Azure Commercial. I just deployed a template which uses this feature, and I got the error throw on one of my role assignments even though the onIfNotExists decorator is present. Interestingly, I do NOT get the template version error we're talking about.

@slavizh
Copy link
Copy Markdown
Contributor

slavizh commented Oct 7, 2025

@jcbartle the feature does not fix the problem with role assignments. The feature checks if the resource exists by name. When exists does not deploy it again and when it does not exists deploys it. The role assignment issue is because you cannot have the same role and principal role assignment deployed if such already exists by another name.

@jcbartle
Copy link
Copy Markdown

jcbartle commented Oct 7, 2025

@slavizh - I know that this PR doesn't address the RoleAssignmentExists issue. I was asking above if perhaps it had been fixed elsewhere. Also just highlighting the differences between environments (Commercial versus Government).

@jcbartle
Copy link
Copy Markdown

jcbartle commented Oct 7, 2025

@tsmallig33 - just ran one template using two parameter files, one in Commercial and one in Government. Can confirm that the Deployment template validation failed: 'Template language version '2.0' does not support feature 'OnlyIfNotExists'.'. (Code:InvalidTemplate) error only occurs in Government.

Correlation ID: cf24425b-901e-4869-b1d7-88b3925ee62d

@tsmallig33
Copy link
Copy Markdown
Member Author

Thanks for providing more details. As a temporary workaround in Government, you can either try to switch to bicep v0.37 or if you can edit the json template, you can set the languageVersion to 2.1-experimental.

@tsmallig33
Copy link
Copy Markdown
Member Author

Hi @jcbartle - it is possible that there was an update that was not fully rolled out in Government. It is now showing as fully rolled out, so would it be possible for you to retry the deployment and share the correlationId once again?

@jcbartle
Copy link
Copy Markdown

Hello, @tsmallig33. Thanks for the response. Reran a template back-to-back in Commercial and Government.

Bicep CLI version 0.38.33
Experimental features section of my bicepconfig.json file is removed / no longer present.

No errors related to template language version!!! So I think that part is fixed - thank you. In the Government deployment, I get no errors or strange behavior at all. In the Commercial deployment, it seems that the onlyIfNotExists decorator is getting ignored when applying a role assignment to a resource group. That's the only time I'm getting the erroneous "The role assignment already exists." error. Applying role assignments on other resource types does not throw this error. Correlation ID: 50f20a23-50f0-4f55-9291-1f9ca5f26d72

@tsmallig33
Copy link
Copy Markdown
Member Author

Hi @jcbartle, thanks for the update. For the deployment with correlationId 50f20a23-50f0-4f55-9291-1f9ca5f26d72, the role assignment that is failing is returning not found when searched for by name/id, so a create is attempted. During the create, we are receiving the "The role assignment already exists" conflict error which indicates there may be an existing role assignment with a different id or name which onlyIfNotExists will not fix.

@mumian
Copy link
Copy Markdown
Contributor

mumian commented Oct 23, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants