Skip to content

Commit 7bc3cfc

Browse files
643 vm size nesting fix (#682)
* VM-Size-Should-Be-A-Parameter nesting fix (Fixes #643) * Adding test for nested VMSize (Fixes #643) * Adding vmSize parameter to passing example * Updating vmSize test (only matching top-level parameters) * Adding Failure Case Co-authored-by: James Brundage <@github.com>
1 parent dd36b59 commit 7bc3cfc

File tree

4 files changed

+263
-7
lines changed

4 files changed

+263
-7
lines changed

arm-ttk/testcases/deploymentTemplate/VM-Size-Should-Be-A-Parameter.test.ps1

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,74 @@
55
Ensures that the Sizes of a virtual machine in a template are parameters
66
#>
77
param(
8+
# The template object, with inline templates removed to keep the proper scope of tests when parsing - could be the mainTemplate.json or a nested template.
89
[Parameter(Mandatory = $true)]
910
[PSObject]
10-
$TemplateObject
11+
$TemplateObject,
12+
13+
# The original mainTemplate.json object, without any modifications - nested templates are still inline ($TemplateObject has replaced any inner templates with blanks).
14+
[PSObject]
15+
$OriginalTemplateObject,
16+
17+
# The list of inner templates
18+
[PSObject[]]
19+
$InnerTemplates,
20+
21+
# If set, the current -TemplateObject is an inner template.
22+
[switch]
23+
$IsInnerTemplate
1124
)
1225

13-
$vmSizes = $TemplateObject.resources | Find-JsonContent -Key vmSize -Value * -Like
26+
if ($IsInnerTemplate) { return } # If we are evaluating an inner template, return (this test should run once per file)
27+
if (-not $OriginalTemplateObject) { return} # If there was no original template object, then there is nothing to check.
1428

29+
# Get all VMSizes used throughout the template and any inner templates
30+
$vmSizes = Find-JsonContent -Key vmSize -Value * -Like -inputObject $OriginalTemplateObject
31+
$vmSizeTopLevelParameterDeclared = $false
1532
foreach ($vmSizeObject in $vmSizes) {
1633

1734
$vmSize = $vmSizeObject.vmSize
35+
# If the vmSize was in a parameter, we will want to continue
36+
if ($vmSizeObject.JSONPath -match '^parameters\.vmsize$') {
37+
# but not before we check if it was an inner template
38+
if ($vmSizeObject.ParentObject[0].expressionEvaluationOptions.scope -eq 'inner') {
39+
# If it was an inner template, check to make sure that the inner template contains a vmSize
40+
if (-not $vmSize.Value | ?<ARM_Parameter> -Parameter vmSize) {
41+
Write-Error "Nested template parameter vmSize does not map to vmSize parameter" -TargetObject $vmSizeObject
42+
continue
43+
}
44+
} else {
45+
# Otherwise, make note of the fact that we have a parameter called VMSize
46+
$vmSizeTopLevelParameterDeclared = $true
47+
}
48+
continue
49+
}
50+
51+
# The only other places we should find VMSizes are in resources.
52+
53+
# Keep track of the type and name.
1854
$resourceType = $vmSizeObject.ParentObject.type
1955
$resourceName = $vmSizeObject.ParentObject.name
20-
21-
if ($vmSize -notmatch "\s{0,}\[.*?parameters\s{0,}\(\s{0,}'") {
22-
if ($vmSize -match "\s{0,}\[.*?variables\s{0,}\(\s{0,}'") {
23-
$resolvedVmSize = Expand-AzTemplate -Expression $vmSize -InputObject $TemplateObject
56+
57+
58+
if (-not $vmSize | ?<ARM_Parameter>) { # If the VMSize does not have a parameter reference
59+
if ($vmSize | ?<ARM_Variable>) { # but does have a variable reference
60+
# try expanding the variable
61+
$resolvedVmSize = Expand-AzTemplate -Expression $vmSize -InputObject $OriginalTemplateObject
62+
# if the expanded variable does not contain a parameter
2463
if ($resolvedVmSize -notmatch "\s{0,}\[.*?parameters\s{0,}\(\s{0,}'") {
64+
# write an error.
2565
Write-Error "VM Size for resourceType '$resourceType' named '$resourceName' must be a parameter" -TargetObject $vm
2666
}
2767
}
2868
else {
69+
# If the vmSize had no variable or parameter references, write an error.
2970
Write-Error "VM Size for resourceType '$resourceType' named '$resourceName' must be a parameter" -TargetObject $vm
3071
}
3172
}
32-
3373
}
74+
75+
if ($vmSizes -and -not $vmSizeTopLevelParameterDeclared) {
76+
Write-Error "VMSize parameter must be declared for the parent template"
77+
return
78+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
{
2+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
3+
"contentVersion": "1.0.0.0",
4+
"parameters": {
5+
},
6+
"resources": [
7+
{
8+
"type": "Microsoft.Resources/deployments",
9+
"apiVersion": "2020-10-01",
10+
"name": "nested-child",
11+
"properties": {
12+
"expressionEvaluationOptions": {
13+
"scope": "inner"
14+
},
15+
"mode": "Incremental",
16+
"parameters": {
17+
"vmSize": {
18+
"value": "[parameters('vmSize')]"
19+
}
20+
},
21+
"template": {
22+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
23+
"contentVersion": "1.0.0.0",
24+
"parameters": {
25+
"vmSize": {
26+
"type": "string",
27+
"metadata": {
28+
"description": "VM size for the default compute cluster"
29+
}
30+
}
31+
},
32+
"resources": [
33+
{
34+
"type": "Microsoft.Resources/deployments",
35+
"apiVersion": "2020-10-01",
36+
"name": "nested-granchild",
37+
"properties": {
38+
"expressionEvaluationOptions": {
39+
"scope": "inner"
40+
},
41+
"mode": "Incremental",
42+
"parameters": {
43+
"vmSize": {
44+
"value": "[parameters('vmSize')]"
45+
}
46+
},
47+
"template": {
48+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
49+
"contentVersion": "1.0.0.0",
50+
"parameters": {
51+
"vmSize": {
52+
"type": "string",
53+
"metadata": {
54+
"description": "VM size for the default compute cluster"
55+
}
56+
}
57+
},
58+
"resources": [
59+
{
60+
"type": "Microsoft.Resources/deployments",
61+
"apiVersion": "2020-10-01",
62+
"name": "nested-great-grandchild",
63+
"properties": {
64+
"expressionEvaluationOptions": {
65+
"scope": "inner"
66+
},
67+
"mode": "Incremental",
68+
"parameters": {
69+
},
70+
"template": {
71+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
72+
"contentVersion": "1.0.0.0",
73+
"parameters": {
74+
"vmSize": { // this was the original bug - everything above was preserved from the original template but the param name was changed
75+
"type": "string",
76+
"defaultValue": "Standard_DS2_v2",
77+
"metadata": {
78+
"description": "Size of the virtual machine"
79+
}
80+
}
81+
},
82+
"resources": [
83+
],
84+
"outputs": {
85+
"vmSize": {
86+
"type": "string",
87+
"value": "[parameters('vmSize')]"
88+
}
89+
}
90+
}
91+
}
92+
}
93+
]
94+
}
95+
}
96+
}
97+
]
98+
}
99+
}
100+
}
101+
]
102+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
{
2+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
3+
"contentVersion": "1.0.0.0",
4+
"parameters": {
5+
"vmSize": {
6+
"type": "string",
7+
"defaultValue": "Standard_DS3_v2"
8+
}
9+
},
10+
"resources": [
11+
{
12+
"type": "Microsoft.Resources/deployments",
13+
"apiVersion": "2020-10-01",
14+
"name": "nested-child",
15+
"properties": {
16+
"expressionEvaluationOptions": {
17+
"scope": "inner"
18+
},
19+
"mode": "Incremental",
20+
"parameters": {
21+
"vmSize": {
22+
"value": "[parameters('vmSize')]"
23+
}
24+
},
25+
"template": {
26+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
27+
"contentVersion": "1.0.0.0",
28+
"parameters": {
29+
"vmSize": {
30+
"type": "string",
31+
"metadata": {
32+
"description": "VM size for the default compute cluster"
33+
}
34+
}
35+
},
36+
"resources": [
37+
{
38+
"type": "Microsoft.Resources/deployments",
39+
"apiVersion": "2020-10-01",
40+
"name": "nested-granchild",
41+
"properties": {
42+
"expressionEvaluationOptions": {
43+
"scope": "inner"
44+
},
45+
"mode": "Incremental",
46+
"parameters": {
47+
"vmSize": {
48+
"value": "[parameters('vmSize')]"
49+
}
50+
},
51+
"template": {
52+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
53+
"contentVersion": "1.0.0.0",
54+
"parameters": {
55+
"vmSize": {
56+
"type": "string",
57+
"metadata": {
58+
"description": "VM size for the default compute cluster"
59+
}
60+
}
61+
},
62+
"resources": [
63+
{
64+
"type": "Microsoft.Resources/deployments",
65+
"apiVersion": "2020-10-01",
66+
"name": "nested-great-grandchild",
67+
"properties": {
68+
"expressionEvaluationOptions": {
69+
"scope": "inner"
70+
},
71+
"mode": "Incremental",
72+
"parameters": {
73+
},
74+
"template": {
75+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
76+
"contentVersion": "1.0.0.0",
77+
"parameters": {
78+
"vmSize": { // this was the original bug - everything above was preserved from the original template but the param name was changed
79+
"type": "string",
80+
"defaultValue": "Standard_DS2_v2",
81+
"metadata": {
82+
"description": "Size of the virtual machine"
83+
}
84+
}
85+
},
86+
"resources": [
87+
],
88+
"outputs": {
89+
"vmSize": {
90+
"type": "string",
91+
"value": "[parameters('vmSize')]"
92+
}
93+
}
94+
}
95+
}
96+
}
97+
]
98+
}
99+
}
100+
}
101+
]
102+
}
103+
}
104+
}
105+
]
106+
}

unit-tests/VM-Size-Should-Be-A-Parameter/Pass/VMSize-In-Alternate-VMTypes.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
{
22
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
33
"contentVersion": "1.0.0.0",
4+
"parameters": {
5+
"vmSize": {}
6+
},
47
"resources": [
58
{
69
"type": "Microsoft.MachineLearningServices/workspaces/computes",

0 commit comments

Comments
 (0)