From bd23a0e8cbae821ef4a82d6e21984416a6fb9709 Mon Sep 17 00:00:00 2001 From: Khanh Le Date: Mon, 15 Jun 2026 13:45:37 -0500 Subject: [PATCH 1/2] Allow roleDefinitions in resource ID lint rule --- .../UseResourceIdFunctionsRuleTests.cs | 18 +++++++++++++++++- .../Linter/Rules/UseResourceIdFunctionsRule.cs | 12 +++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/Bicep.Core.UnitTests/Diagnostics/LinterRuleTests/UseResourceIdFunctionsRuleTests.cs b/src/Bicep.Core.UnitTests/Diagnostics/LinterRuleTests/UseResourceIdFunctionsRuleTests.cs index bb4b15c50aa..1eb9a864b4b 100644 --- a/src/Bicep.Core.UnitTests/Diagnostics/LinterRuleTests/UseResourceIdFunctionsRuleTests.cs +++ b/src/Bicep.Core.UnitTests/Diagnostics/LinterRuleTests/UseResourceIdFunctionsRuleTests.cs @@ -11,7 +11,7 @@ namespace Bicep.Core.UnitTests.Diagnostics.LinterRuleTests [TestClass] public class UseResourceIdFunctionsRuleTests : LinterRuleTestsBase { - private const string allowedFunctions = "extensionResourceId, guid, if, managementGroupResourceId, reference, resourceId, subscription, subscriptionResourceId, tenantResourceId"; + private const string allowedFunctions = "extensionResourceId, guid, if, managementGroupResourceId, reference, resourceId, roleDefinitions, subscription, subscriptionResourceId, tenantResourceId"; private static void CompileAndTest(string bicep, params string[] expectedMessages) { @@ -1973,6 +1973,22 @@ param parTopLevelManagementGroupParentId string } } } +", + expectedMessages: []); + } + + [TestMethod] + public void RoleDefinitionFunctionPropertyAccessShouldPass() + { + CompileAndTest( + @" + resource sample 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: '00000000-0000-0000-0000-000000000000' + properties: { + roleDefinitionId: roleDefinitions('Monitoring Metrics Publisher').id + principalId: '00000000-0000-0000-0000-000000000000' + } + } ", expectedMessages: []); } diff --git a/src/Bicep.Core/Analyzers/Linter/Rules/UseResourceIdFunctionsRule.cs b/src/Bicep.Core/Analyzers/Linter/Rules/UseResourceIdFunctionsRule.cs index ecd367201bb..81ec8629940 100644 --- a/src/Bicep.Core/Analyzers/Linter/Rules/UseResourceIdFunctionsRule.cs +++ b/src/Bicep.Core/Analyzers/Linter/Rules/UseResourceIdFunctionsRule.cs @@ -29,6 +29,7 @@ public UseResourceIdFunctionsRule() : base( "managementGroupResourceId", "reference", "resourceId", + "roleDefinitions", "subscription", "subscriptionResourceId", "tenantResourceId", @@ -265,6 +266,14 @@ private static ResourceIdStatus IsResourceIdProperty(ObjectPropertySyntax Proper return null; } break; + case AccessExpressionSyntax accessExpression: + if (IsParameterPropertyAccess(model, accessExpression)) + { + // parameter properties are always okay + return null; + } + + return AnalyzeIdPropertyValue(model, propertySyntax, accessExpression.BaseExpression, currentPaths); case VariableAccessSyntax: // Variable and parameter access if (model.GetSymbolInfo(expression) is DeclaredSymbol symbol) { @@ -286,9 +295,6 @@ private static ResourceIdStatus IsResourceIdProperty(ObjectPropertySyntax Proper } } break; - case AccessExpressionSyntax accessExpression when IsParameterPropertyAccess(model, accessExpression): - // parameter properties are always okay - return null; case TernaryOperationSyntax: // "if"/ternary is acceptable return null; From 2687fa60761701886da1115744ad19c93f0018e8 Mon Sep 17 00:00:00 2001 From: Khanh Le Date: Thu, 18 Jun 2026 11:41:15 -0500 Subject: [PATCH 2/2] Update InvalidResources CRLF diagnostics baseline --- .../InvalidResources_CRLF/main.diagnostics.bicep | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Bicep.Core.Samples/Files/baselines/InvalidResources_CRLF/main.diagnostics.bicep b/src/Bicep.Core.Samples/Files/baselines/InvalidResources_CRLF/main.diagnostics.bicep index 3f7e21e08d5..3f5ef6c963c 100644 --- a/src/Bicep.Core.Samples/Files/baselines/InvalidResources_CRLF/main.diagnostics.bicep +++ b/src/Bicep.Core.Samples/Files/baselines/InvalidResources_CRLF/main.diagnostics.bicep @@ -1655,7 +1655,7 @@ resource propertyLoopsCannotNest 'Microsoft.Storage/storageAccounts@2019-06-01' networkAcls: { virtualNetworkRules: [for rule in []: { id: '${account.name}-${account.location}' -//@[008:010) [use-resource-id-functions (Warning)] If property "id" represents a resource ID, it must use a symbolic resource reference, be a parameter or start with one of these functions: extensionResourceId, guid, if, managementGroupResourceId, reference, resourceId, subscription, subscriptionResourceId, tenantResourceId. (bicep core linter https://aka.ms/bicep/linter-diagnostics#use-resource-id-functions) |id| +//@[008:010) [use-resource-id-functions (Warning)] If property "id" represents a resource ID, it must use a symbolic resource reference, be a parameter or start with one of these functions: extensionResourceId, guid, if, managementGroupResourceId, reference, resourceId, roleDefinitions, subscription, subscriptionResourceId, tenantResourceId. (bicep core linter https://aka.ms/bicep/linter-diagnostics#use-resource-id-functions) |id| state: [for lol in []: 4] //@[016:019) [BCP142 (Error)] Property value for-expressions cannot be nested. (bicep https://aka.ms/bicep/core-diagnostics#BCP142) |for| }] @@ -1676,7 +1676,7 @@ resource propertyLoopsCannotNest2 'Microsoft.Storage/storageAccounts@2019-06-01' networkAcls: { virtualNetworkRules: [for (rule,j) in []: { id: '${account.name}-${account.location}' -//@[008:010) [use-resource-id-functions (Warning)] If property "id" represents a resource ID, it must use a symbolic resource reference, be a parameter or start with one of these functions: extensionResourceId, guid, if, managementGroupResourceId, reference, resourceId, subscription, subscriptionResourceId, tenantResourceId. (bicep core linter https://aka.ms/bicep/linter-diagnostics#use-resource-id-functions) |id| +//@[008:010) [use-resource-id-functions (Warning)] If property "id" represents a resource ID, it must use a symbolic resource reference, be a parameter or start with one of these functions: extensionResourceId, guid, if, managementGroupResourceId, reference, resourceId, roleDefinitions, subscription, subscriptionResourceId, tenantResourceId. (bicep core linter https://aka.ms/bicep/linter-diagnostics#use-resource-id-functions) |id| state: [for (lol,k) in []: 4] //@[016:019) [BCP142 (Error)] Property value for-expressions cannot be nested. (bicep https://aka.ms/bicep/core-diagnostics#BCP142) |for| }] @@ -1699,7 +1699,7 @@ resource propertyLoopsCannotNest2 'Microsoft.Storage/storageAccounts@2019-06-01' virtualNetworkRules: [for rule in []: { // #completionTest(15,31) -> symbolsPlusRule id: '${account.name}-${account.location}' -//@[008:010) [use-resource-id-functions (Warning)] If property "id" represents a resource ID, it must use a symbolic resource reference, be a parameter or start with one of these functions: extensionResourceId, guid, if, managementGroupResourceId, reference, resourceId, subscription, subscriptionResourceId, tenantResourceId. (bicep core linter https://aka.ms/bicep/linter-diagnostics#use-resource-id-functions) |id| +//@[008:010) [use-resource-id-functions (Warning)] If property "id" represents a resource ID, it must use a symbolic resource reference, be a parameter or start with one of these functions: extensionResourceId, guid, if, managementGroupResourceId, reference, resourceId, roleDefinitions, subscription, subscriptionResourceId, tenantResourceId. (bicep core linter https://aka.ms/bicep/linter-diagnostics#use-resource-id-functions) |id| state: [for state in []: { //@[016:019) [BCP142 (Error)] Property value for-expressions cannot be nested. (bicep https://aka.ms/bicep/core-diagnostics#BCP142) |for| // #completionTest(38) -> empty #completionTest(16) -> symbolsPlusAccountRuleState @@ -1725,7 +1725,7 @@ resource stuffs 'Microsoft.Storage/storageAccounts@2019-06-01' = [for account in virtualNetworkRules: concat([for lol in []: { //@[035:038) [BCP138 (Error)] For-expressions are not supported in this context. For-expressions may be used as values of resource, module, variable, and output declarations, or values of resource and module properties. (bicep https://aka.ms/bicep/core-diagnostics#BCP138) |for| id: '${account.name}-${account.location}' -//@[008:010) [use-resource-id-functions (Warning)] If property "id" represents a resource ID, it must use a symbolic resource reference, be a parameter or start with one of these functions: extensionResourceId, guid, if, managementGroupResourceId, reference, resourceId, subscription, subscriptionResourceId, tenantResourceId. (bicep core linter https://aka.ms/bicep/linter-diagnostics#use-resource-id-functions) |id| +//@[008:010) [use-resource-id-functions (Warning)] If property "id" represents a resource ID, it must use a symbolic resource reference, be a parameter or start with one of these functions: extensionResourceId, guid, if, managementGroupResourceId, reference, resourceId, roleDefinitions, subscription, subscriptionResourceId, tenantResourceId. (bicep core linter https://aka.ms/bicep/linter-diagnostics#use-resource-id-functions) |id| }]) } }