Skip to content

Commit 6d02f7b

Browse files
authored
Fixed MG scope deployment link Azure#3013 (Azure#3019)
* Fixed MG scope deployment link Azure#3013 * Fix .NET docs build * Remove separated test * Fix subscription aliases for tagging
1 parent 39aa1e4 commit 6d02f7b

12 files changed

+223
-18
lines changed

.github/workflows/build.yaml

-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ on:
1616
env:
1717
DOTNET_NOLOGO: true
1818
DOTNET_CLI_TELEMETRY_OPTOUT: true
19-
DOTNET_VERSION: 8.x
2019

2120
jobs:
2221
build:
@@ -32,8 +31,6 @@ jobs:
3231

3332
- name: Setup .NET
3433
uses: actions/setup-dotnet@v4
35-
with:
36-
dotnet-version: ${{ env.DOTNET_VERSION }}
3734

3835
- name: Install dependencies
3936
shell: pwsh
@@ -110,8 +107,6 @@ jobs:
110107

111108
- name: Setup .NET
112109
uses: actions/setup-dotnet@v4
113-
with:
114-
dotnet-version: ${{ env.DOTNET_VERSION }}
115110

116111
- if: ${{ matrix.shell == 'pwsh' }}
117112
name: Install dependencies (PowerShell)

.github/workflows/docs.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ jobs:
4141
python-version: '3.11'
4242
architecture: x64
4343

44+
- name: Setup .NET
45+
uses: actions/setup-dotnet@v4
46+
4447
- name: Install dependencies
4548
run: |
4649
python3 -m pip install --upgrade pip

docs/CHANGELOG-v1.md

+5
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ What's changed since pre-release v1.39.0-B0029:
4141
- Engineering:
4242
- Bump development tools to .NET 8.0 SDK by @BernieWhite.
4343
[#3017](https://github.com/Azure/PSRule.Rules.Azure/issues/3017)
44+
- Bug fixed:
45+
- Fixed expansion with deployments by resource ID at management group by @BernieWhite
46+
[#3013](https://github.com/Azure/PSRule.Rules.Azure/issues/3013)
47+
- Fixed subscription aliases don't support tags by @BernieWhite.
48+
[#3021](https://github.com/Azure/PSRule.Rules.Azure/issues/3021)
4449

4550
## v1.39.0-B0029 (pre-release)
4651

src/PSRule.Rules.Azure/Common/ResourceHelper.cs

+3
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,9 @@ private static bool ConsumeProvidersPart(string[] parts, ref int start, out stri
376376
if (start + 3 < parts.Length && StringComparer.OrdinalIgnoreCase.Equals(parts[start], PROVIDERS))
377377
start++;
378378

379+
if (start == 0 && StringComparer.OrdinalIgnoreCase.Equals(parts[1], PROVIDERS))
380+
start += 2;
381+
379382
provider = parts[start++];
380383
type = parts[start++];
381384
name = parts[start++];

src/PSRule.Rules.Azure/Data/Template/TemplateVisitor.cs

+16-4
Original file line numberDiff line numberDiff line change
@@ -281,14 +281,23 @@ internal void Load(JObject parameters)
281281
internal bool TryParentResourceId(JObject resource, out string[] resourceId)
282282
{
283283
resourceId = null;
284-
if (!TryResourceScope(resource, out var id) ||
285-
!ResourceHelper.TryResourceIdComponents(id, out var subscriptionId, out var resourceGroupName, out string[] resourceTypeComponents, out string[] nameComponents))
284+
if (!TryResourceScope(resource, out var id))
285+
return false;
286+
287+
if (id == TENANT_SCOPE)
288+
{
289+
resourceId = new string[] { TENANT_SCOPE };
290+
return true;
291+
}
292+
293+
if (!ResourceHelper.TryResourceIdComponents(id, out var subscriptionId, out var resourceGroupName, out string[] resourceTypeComponents, out string[] nameComponents))
286294
return false;
287295

288296
resourceId = new string[nameComponents.Length];
289297
for (var i = 0; i < nameComponents.Length; i++)
298+
{
290299
resourceId[i] = ResourceHelper.CombineResourceId(subscriptionId, resourceGroupName, resourceTypeComponents, nameComponents, depth: i);
291-
300+
}
292301
return resourceId.Length > 0;
293302
}
294303

@@ -1331,7 +1340,10 @@ private static ResourceValue ResourceInstance(TemplateContext context, JObject r
13311340
else if (deploymentScope == DeploymentScope.Subscription)
13321341
resourceId = ResourceHelper.CombineResourceId(subscriptionId, null, type, name);
13331342

1334-
else if (deploymentScope == DeploymentScope.ManagementGroup || deploymentScope == DeploymentScope.Tenant)
1343+
else if (deploymentScope == DeploymentScope.ManagementGroup)
1344+
resourceId = ResourceHelper.CombineResourceId(null, null, type, name, scope: scope ?? context.Deployment.Scope);
1345+
1346+
else if (deploymentScope == DeploymentScope.Tenant)
13351347
resourceId = ResourceHelper.CombineResourceId(null, null, type, name);
13361348

13371349
context.UpdateResourceScope(resource);

src/PSRule.Rules.Azure/rules/Common.Selector.Rule.yaml

+17
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,25 @@ spec:
4646
# Exclude resource providers that do not support tags
4747
- type: '.'
4848
notStartsWith:
49+
- Microsoft.ADHybridHealthService/
4950
- Microsoft.Addons/
5051
- Microsoft.Advisor/
5152
- Microsoft.Billing/
53+
- Microsoft.BillingBenefits/
5254
- Microsoft.Blueprint/
5355
- Microsoft.Capacity/
56+
- Microsoft.ChangeAnalysis/
5457
- Microsoft.Classic
58+
- Microsoft.Commerce/
5559
- Microsoft.Consumption/
60+
- Microsoft.CustomerLockbox/
61+
- Microsoft.Features/
5662
- Microsoft.Gallery/
63+
- Microsoft.GuestConfiguration/
64+
- Microsoft.HybridConnectivity/
65+
- Microsoft.IoTSecurity/
5766
- Microsoft.Security/
67+
- Microsoft.Subscription/
5868
- microsoft.support/
5969
- Microsoft.WorkloadMonitor/
6070
- Microsoft.ManagedServices/
@@ -134,6 +144,13 @@ spec:
134144
- Microsoft.Insights/workbooks
135145
- Microsoft.Insights/workbookTemplates
136146

147+
- anyOf:
148+
- type: '.'
149+
notStartsWith: Microsoft.Chaos/
150+
- type: '.'
151+
in:
152+
- Microsoft.Chaos/experiments
153+
137154
- anyOf:
138155
- type: '.'
139156
notLike: 'Microsoft.*/*/*'

tests/PSRule.Rules.Azure.Tests/TemplateVisitorTests.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,7 @@ public void ContainsWithJValue()
986986
public void ManagementGroupScopedResource()
987987
{
988988
var resources = ProcessTemplate(GetSourcePath("Tests.Bicep.31.json"), null, out _);
989-
Assert.Equal(4, resources.Length);
989+
Assert.Equal(9, resources.Length);
990990

991991
var actual = resources[1];
992992
Assert.Equal("Microsoft.Subscription/aliases", actual["type"].Value<string>());

tests/PSRule.Rules.Azure.Tests/Tests.Bicep.31.bicep

+14-2
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,23 @@ resource subscriptionAlias 'Microsoft.Subscription/aliases@2021-10-01' = {
99
properties: {
1010
workload: 'DevTest'
1111
displayName: 'sub1'
12-
billingScope: ' /billingAccounts/nn/enrollmentAccounts/nn'
12+
billingScope: '/billingAccounts/nn/enrollmentAccounts/nn'
1313
}
1414
}
1515

1616
module rbac './Tests.Bicep.31.child.bicep' = {
1717
scope: subscription('00000000-0000-0000-0000-000000000000')
18-
name: 'rbac'
18+
name: 'child'
19+
}
20+
21+
module createSubscription './Tests.Bicep.31.child2.bicep' = {
22+
name: 'child2'
23+
scope: managementGroup()
24+
}
25+
26+
module createSubscriptionResources './Tests.Bicep.31.child3.bicep' = {
27+
name: 'child3'
28+
params: {
29+
subscriptionId: createSubscription.outputs.subscriptionId
30+
}
1931
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
targetScope = 'managementGroup'
5+
6+
resource subscriptionAlias 'Microsoft.Subscription/aliases@2021-10-01' = {
7+
scope: tenant()
8+
name: 'sub2'
9+
properties: {
10+
workload: 'DevTest'
11+
displayName: 'sub2'
12+
billingScope: '/billingAccounts/nn/enrollmentAccounts/nn'
13+
}
14+
}
15+
16+
output subscriptionId string = subscriptionAlias.properties.subscriptionId
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
targetScope = 'managementGroup'
5+
6+
param subscriptionId string
7+
8+
module deploySub './Tests.Bicep.31.child4.bicep' = {
9+
name: 'child4'
10+
scope: subscription(subscriptionId)
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
targetScope = 'subscription'
5+
6+
resource assignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
7+
name: '48d15605-70a3-4676-bb6a-792f403786b5'
8+
properties: {
9+
principalId: '48d15605-70a3-4676-bb6a-792f403786b5'
10+
roleDefinitionId: '48d15605-70a3-4676-bb6a-792f403786b5'
11+
principalType: 'ServicePrincipal'
12+
description: 'Test role assignment for checking scope and ID.'
13+
}
14+
}

tests/PSRule.Rules.Azure.Tests/Tests.Bicep.31.json

+123-6
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
"metadata": {
55
"_generator": {
66
"name": "bicep",
7-
"version": "0.23.1.45101",
8-
"templateHash": "1432163185374769317"
7+
"version": "0.29.47.4906",
8+
"templateHash": "18243599897785785680"
99
}
1010
},
1111
"resources": [
@@ -17,13 +17,13 @@
1717
"properties": {
1818
"workload": "DevTest",
1919
"displayName": "sub1",
20-
"billingScope": " /billingAccounts/nn/enrollmentAccounts/nn"
20+
"billingScope": "/billingAccounts/nn/enrollmentAccounts/nn"
2121
}
2222
},
2323
{
2424
"type": "Microsoft.Resources/deployments",
2525
"apiVersion": "2022-09-01",
26-
"name": "rbac",
26+
"name": "child",
2727
"subscriptionId": "00000000-0000-0000-0000-000000000000",
2828
"location": "[deployment().location]",
2929
"properties": {
@@ -37,8 +37,8 @@
3737
"metadata": {
3838
"_generator": {
3939
"name": "bicep",
40-
"version": "0.23.1.45101",
41-
"templateHash": "17477755083280448345"
40+
"version": "0.29.47.4906",
41+
"templateHash": "4248553621957476478"
4242
}
4343
},
4444
"resources": [
@@ -56,6 +56,123 @@
5656
]
5757
}
5858
}
59+
},
60+
{
61+
"type": "Microsoft.Resources/deployments",
62+
"apiVersion": "2022-09-01",
63+
"name": "child2",
64+
"location": "[deployment().location]",
65+
"properties": {
66+
"expressionEvaluationOptions": {
67+
"scope": "inner"
68+
},
69+
"mode": "Incremental",
70+
"template": {
71+
"$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#",
72+
"contentVersion": "1.0.0.0",
73+
"metadata": {
74+
"_generator": {
75+
"name": "bicep",
76+
"version": "0.29.47.4906",
77+
"templateHash": "16465737476591302057"
78+
}
79+
},
80+
"resources": [
81+
{
82+
"type": "Microsoft.Subscription/aliases",
83+
"apiVersion": "2021-10-01",
84+
"scope": "/",
85+
"name": "sub2",
86+
"properties": {
87+
"workload": "DevTest",
88+
"displayName": "sub2",
89+
"billingScope": "/billingAccounts/nn/enrollmentAccounts/nn"
90+
}
91+
}
92+
],
93+
"outputs": {
94+
"subscriptionId": {
95+
"type": "string",
96+
"value": "[reference(tenantResourceId('Microsoft.Subscription/aliases', 'sub2'), '2021-10-01').subscriptionId]"
97+
}
98+
}
99+
}
100+
}
101+
},
102+
{
103+
"type": "Microsoft.Resources/deployments",
104+
"apiVersion": "2022-09-01",
105+
"name": "child3",
106+
"location": "[deployment().location]",
107+
"properties": {
108+
"expressionEvaluationOptions": {
109+
"scope": "inner"
110+
},
111+
"mode": "Incremental",
112+
"parameters": {
113+
"subscriptionId": {
114+
"value": "[reference(extensionResourceId(managementGroup().id, 'Microsoft.Resources/deployments', 'child2'), '2022-09-01').outputs.subscriptionId.value]"
115+
}
116+
},
117+
"template": {
118+
"$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#",
119+
"contentVersion": "1.0.0.0",
120+
"metadata": {
121+
"_generator": {
122+
"name": "bicep",
123+
"version": "0.29.47.4906",
124+
"templateHash": "18410252302990608843"
125+
}
126+
},
127+
"parameters": {
128+
"subscriptionId": {
129+
"type": "string"
130+
}
131+
},
132+
"resources": [
133+
{
134+
"type": "Microsoft.Resources/deployments",
135+
"apiVersion": "2022-09-01",
136+
"name": "child4",
137+
"subscriptionId": "[parameters('subscriptionId')]",
138+
"location": "[deployment().location]",
139+
"properties": {
140+
"expressionEvaluationOptions": {
141+
"scope": "inner"
142+
},
143+
"mode": "Incremental",
144+
"template": {
145+
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
146+
"contentVersion": "1.0.0.0",
147+
"metadata": {
148+
"_generator": {
149+
"name": "bicep",
150+
"version": "0.29.47.4906",
151+
"templateHash": "5988084472097053332"
152+
}
153+
},
154+
"resources": [
155+
{
156+
"type": "Microsoft.Authorization/roleAssignments",
157+
"apiVersion": "2022-04-01",
158+
"name": "48d15605-70a3-4676-bb6a-792f403786b5",
159+
"properties": {
160+
"principalId": "48d15605-70a3-4676-bb6a-792f403786b5",
161+
"roleDefinitionId": "48d15605-70a3-4676-bb6a-792f403786b5",
162+
"principalType": "ServicePrincipal",
163+
"description": "Test role assignment for checking scope and ID."
164+
}
165+
}
166+
]
167+
}
168+
}
169+
}
170+
]
171+
}
172+
},
173+
"dependsOn": [
174+
"[extensionResourceId(managementGroup().id, 'Microsoft.Resources/deployments', 'child2')]"
175+
]
59176
}
60177
]
61178
}

0 commit comments

Comments
 (0)