From 7ce2d113502846d9fdd7401962e42f9dd9f11f90 Mon Sep 17 00:00:00 2001 From: Stephen Weatherford Date: Fri, 28 Jun 2024 13:55:39 -0700 Subject: [PATCH 01/11] Update/fix VM ubuntu snippet --- .../Ubuntu Virtual Machine.snippet.json | 371 ++++++++++-------- test/functional/snippets.test.ts | 26 ++ .../Ubuntu Virtual Machine.snippetresult.json | 367 ++++++++--------- 3 files changed, 421 insertions(+), 343 deletions(-) diff --git a/assets/resourceSnippets/Ubuntu Virtual Machine.snippet.json b/assets/resourceSnippets/Ubuntu Virtual Machine.snippet.json index 504938955..6dda19db5 100644 --- a/assets/resourceSnippets/Ubuntu Virtual Machine.snippet.json +++ b/assets/resourceSnippets/Ubuntu Virtual Machine.snippet.json @@ -3,167 +3,214 @@ "contentVersion": "1.0.0.0", "metadata": { "prefix": "arm-vm-ubuntu", - "description": "Ubuntu Virtual Machine" + "description": "Ubuntu Virtual Machine (see https://learn.microsoft.com/azure/virtual-machines/linux/create-ssh-secured-vm-from-template for more information)" }, - "resources": [ - { - "name": "[toLower('${1:ubuntuVM1}storage')]", - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2023-01-01", - "location": "[resourceGroup().location]", - "tags": { - "displayName": "${1:ubuntuVM1} Storage Account" - }, - "sku": { - "name": /*${2:Standard_LRS}*/ "Standard_LRS" - }, - "kind": /*${3|Storage,StorageV2|}*/ "Storage" - }, - { - "name": "${1:ubuntuVM1}-PublicIP", - "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "2023-04-01", - "location": "[resourceGroup().location]", - "tags": { - "displayName": "PublicIPAddress" - }, - "properties": { - "publicIPAllocationMethod": "Dynamic", - "dnsSettings": { - "domainNameLabel": "[toLower('${1:ubuntuVM1}')]" - } - } - }, - { - "name": "${1:ubuntuVM1}-nsg", - "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "2023-04-01", - "location": "[resourceGroup().location]", - "properties": { - "securityRules": [ - { - "name": "${4:nsgRule1}", - "properties": { - "description": "${5:description}", - "protocol": /*${6|Tcp,Udp,*|}*/ "Tcp", - "sourcePortRange": "${7:*}", - "destinationPortRange": "${8:22}", - "sourceAddressPrefix": "${9:*}", - "destinationAddressPrefix": "${10:*}", - "access": /*${11|Allow,Deny|}*/ "Allow", - "priority": /*${12:100}*/ 100, - "direction": /*${13|Inbound,Outbound|}*/ "Inbound" - } - } - ] - } - }, - { - "name": "${1:ubuntuVM1}-VirtualNetwork", - "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "2023-04-01", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Network/networkSecurityGroups', '${1:ubuntuVM1}-nsg')]" - ], - "tags": { - "displayName": "${1:ubuntuVM1}-VirtualNetwork" - }, - "properties": { - "addressSpace": { - "addressPrefixes": [ - "10.0.0.0/16" - ] - }, - "subnets": [ - { - "name": "${1:ubuntuVM1}-VirtualNetwork-Subnet", - "properties": { - "addressPrefix": "10.0.0.0/24", - "networkSecurityGroup": { - "id": "[resourceId('Microsoft.Network/networkSecurityGroups', '${1:ubuntuVM1}-nsg')]" - } - } - } - ] - } - }, - { - "name": "${1:ubuntuVM1}-NetworkInterface", - "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "2023-04-01", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Network/publicIPAddresses', '${1:ubuntuVM1}-PublicIP')]", - "[resourceId('Microsoft.Network/virtualNetworks', '${1:ubuntuVM1}-VirtualNetwork')]" - ], - "tags": { - "displayName": "${1:ubuntuVM1}-NetworkInterface" - }, - "properties": { - "ipConfigurations": [ - { - "name": "ipConfig1", - "properties": { - "privateIPAllocationMethod": "Dynamic", - "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', '${1:ubuntuVM1}-PublicIP')]" - }, - "subnet": { - "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', '${1:ubuntuVM1}-VirtualNetwork', '${1:ubuntuVM1}-VirtualNetwork-Subnet')]" - } - } - } - ] - } - }, - { - "name": "${1:ubuntuVM1}", - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2023-03-01", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Network/networkInterfaces', '${1:ubuntuVM1}-NetworkInterface')]" - ], - "tags": { - "displayName": "${1:ubuntuVM1}" - }, - "properties": { - "hardwareProfile": { - "vmSize": "Standard_A2_v2" - }, - "osProfile": { - "computerName": "${1:ubuntuVM1}", - "adminUsername": "${14:adminUsername}", - "adminPassword": "${15:adminPassword}" - }, - "storageProfile": { - "imageReference": { - "publisher": "Canonical", - "offer": "UbuntuServer", - "sku": "16.04-LTS", - "version": "latest" - }, - "osDisk": { - "name": "${1:ubuntuVM1}-OSDisk", - "caching": "ReadWrite", - "createOption": "FromImage" - } - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[resourceId('Microsoft.Network/networkInterfaces', '${1:ubuntuVM1}-NetworkInterface')]" - } - ] - }, - "diagnosticsProfile": { - "bootDiagnostics": { - "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', toLower('${1:ubuntuVM1}storage'))).primaryEndpoints.blob]" - } - } - } - } - ] + "parameters": { + "projectName": { + "type": "string", + "metadata": { + "description": "Specifies a name for generating resource names." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Specifies the location for all resources." + } + }, + "adminUsername": { + "type": "string", + "metadata": { + "description": "Specifies a username for the Virtual Machine." + } + }, + "adminPublicKey": { + "type": "string", + "metadata": { + "description": "Specifies the SSH rsa public key file as a string. Use \"ssh-keygen -t rsa -b 2048\" to generate your SSH key pairs." + } + }, + "vmSize": { + "type": "string", + "defaultValue": "Standard_D2s_v3", + "metadata": { + "description": "description" + } + } + }, + "variables": { + "vNetName": "[concat(parameters('projectName'), '-vnet')]", + "vNetAddressPrefixes": "10.0.0.0/16", + "vNetSubnetName": "default", + "vNetSubnetAddressPrefix": "10.0.0.0/24", + "vmName": "[concat(parameters('projectName'), '-vm')]", + "publicIPAddressName": "[concat(parameters('projectName'), '-ip')]", + "networkInterfaceName": "[concat(parameters('projectName'), '-nic')]", + "networkSecurityGroupName": "[concat(parameters('projectName'), '-nsg')]", + "networkSecurityGroupName2": "[concat(variables('vNetSubnetName'), '-nsg')]" + }, + "resources": [ + { + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2020-05-01", + "name": "[variables('networkSecurityGroupName')]", + "location": "[parameters('location')]", + "properties": { + "securityRules": [ + { + "name": "ssh_rule", + "properties": { + "description": "Locks inbound down to ssh default port 22.", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "22", + "sourceAddressPrefix": "*", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 123, + "direction": "Inbound" + } + } + ] + } + }, + { + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2020-05-01", + "name": "[variables('publicIPAddressName')]", + "location": "[parameters('location')]", + "properties": { + "publicIPAllocationMethod": "Dynamic" + }, + "sku": { + "name": "Basic" + } + }, + { + "comments": "Simple Network Security Group for subnet [variables('vNetSubnetName')]", + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2020-05-01", + "name": "[variables('networkSecurityGroupName2')]", + "location": "[parameters('location')]", + "properties": { + "securityRules": [ + { + "name": "default-allow-22", + "properties": { + "priority": 1000, + "access": "Allow", + "direction": "Inbound", + "destinationPortRange": "22", + "protocol": "Tcp", + "sourceAddressPrefix": "*", + "sourcePortRange": "*", + "destinationAddressPrefix": "*" + } + } + ] + } + }, + { + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2020-05-01", + "name": "[variables('vNetName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName2'))]" + ], + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('vNetAddressPrefixes')]" + ] + }, + "subnets": [ + { + "name": "[variables('vNetSubnetName')]", + "properties": { + "addressPrefix": "[variables('vNetSubnetAddressPrefix')]", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName2'))]" + } + } + } + ] + } + }, + { + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "2020-05-01", + "name": "[variables('networkInterfaceName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]", + "[resourceId('Microsoft.Network/virtualNetworks', variables('vNetName'))]", + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + }, + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vNetName'), variables('vNetSubnetName'))]" + } + } + } + ] + } + }, + { + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2021-11-01", + "name": "[variables('vmName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]" + ], + "properties": { + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "osProfile": { + "computerName": "[variables('vmName')]", + "adminUsername": "[parameters('adminUsername')]", + "linuxConfiguration": { + "disablePasswordAuthentication": true, + "ssh": { + "publicKeys": [ + { + "path": "[concat('/home/', parameters('adminUsername'), '/.ssh/authorized_keys')]", + "keyData": "[parameters('adminPublicKey')]" + } + ] + } + } + }, + "storageProfile": { + "imageReference": { + "publisher": "Canonical", + "offer": "0001-com-ubuntu-server-jammy", + "sku": "22_04-lts-gen2", + "version": "latest" + }, + "osDisk": { + "createOption": "fromImage" + } + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]" + } + ] + } + } + } + ] } diff --git a/test/functional/snippets.test.ts b/test/functional/snippets.test.ts index bf060d68c..e438e0720 100644 --- a/test/functional/snippets.test.ts +++ b/test/functional/snippets.test.ts @@ -252,6 +252,32 @@ const overrideExpectedDiagnostics: { [name: string]: (string | RegExp)[] } = { // TODO: fix snippet "Template validation failed: The template resource 'route-name' for type 'Microsoft.WindowsAzure.ResourceStack.Frontdoor.Common.Entities.TemplateGenericProperty`1[System.String]' at line '5' and column '{COL}' has incorrect segment lengths. A nested resource type must have identical number of segments as its resource name. A root resource type must have segment length one greater than its resource name. Please see https://aka.ms/arm-template/#resources for usage details." ], + "Ubuntu Virtual Machine": [ + "Undefined parameter reference: 'adminPublicKey'", + "Undefined parameter reference: 'adminUsername'", + "Undefined parameter reference: 'adminUsername'", + "Undefined parameter reference: 'vmSize'", + "Undefined variable reference: 'networkInterfaceName'", + "Undefined variable reference: 'networkInterfaceName'", + "Undefined variable reference: 'networkInterfaceName'", + "Undefined variable reference: 'networkSecurityGroupName'", + "Undefined variable reference: 'networkSecurityGroupName'", + "Undefined variable reference: 'networkSecurityGroupName2'", + "Undefined variable reference: 'networkSecurityGroupName2'", + "Undefined variable reference: 'networkSecurityGroupName2'", + "Undefined variable reference: 'publicIPAddressName'", + "Undefined variable reference: 'publicIPAddressName'", + "Undefined variable reference: 'publicIPAddressName'", + "Undefined variable reference: 'vNetAddressPrefixes'", + "Undefined variable reference: 'vNetName'", + "Undefined variable reference: 'vNetName'", + "Undefined variable reference: 'vNetName'", + "Undefined variable reference: 'vNetSubnetAddressPrefix'", + "Undefined variable reference: 'vNetSubnetName'", + "Undefined variable reference: 'vNetSubnetName'", + "Undefined variable reference: 'vmName'", + "Undefined variable reference: 'vmName'" + ], "Windows VM Custom Script": [ // Blocked by https://github.com/Azure/azure-resource-manager-schemas/issues/995 "Missing required property \"commandToExecute\"", diff --git a/test/snippets/expected/Ubuntu Virtual Machine.snippetresult.json b/test/snippets/expected/Ubuntu Virtual Machine.snippetresult.json index 304899593..809f74ba5 100644 --- a/test/snippets/expected/Ubuntu Virtual Machine.snippetresult.json +++ b/test/snippets/expected/Ubuntu Virtual Machine.snippetresult.json @@ -1,182 +1,187 @@ { - "resources": [ - { - "name": "[toLower('ubuntuVM1storage')]", - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2023-01-01", - "location": "[resourceGroup().location]", - "tags": { - "displayName": "ubuntuVM1 Storage Account" - }, - "sku": { - "name": "Standard_LRS" - }, - "kind": "Storage" - }, - { - "name": "ubuntuVM1-PublicIP", - "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "2023-04-01", - "location": "[resourceGroup().location]", - "tags": { - "displayName": "PublicIPAddress" - }, - "properties": { - "publicIPAllocationMethod": "Dynamic", - "dnsSettings": { - "domainNameLabel": "[toLower('ubuntuVM1')]" - } - } - }, - { - "name": "ubuntuVM1-nsg", - "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "2023-04-01", - "location": "[resourceGroup().location]", - "properties": { - "securityRules": [ - { - "name": "nsgRule1", - "properties": { - "description": "description", - "protocol": "Tcp", - "sourcePortRange": "*", - "destinationPortRange": "22", - "sourceAddressPrefix": "*", - "destinationAddressPrefix": "*", - "access": "Allow", - "priority": 100, - "direction": "Inbound" - } - } - ] - } - }, - { - "name": "ubuntuVM1-VirtualNetwork", - "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "2023-04-01", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Network/networkSecurityGroups', 'ubuntuVM1-nsg')]" - ], - "tags": { - "displayName": "ubuntuVM1-VirtualNetwork" - }, - "properties": { - "addressSpace": { - "addressPrefixes": [ - "10.0.0.0/16" - ] - }, - "subnets": [ - { - "name": "ubuntuVM1-VirtualNetwork-Subnet", - "properties": { - "addressPrefix": "10.0.0.0/24", - "networkSecurityGroup": { - "id": "[resourceId('Microsoft.Network/networkSecurityGroups', 'ubuntuVM1-nsg')]" - } - } - } - ] - } - }, - { - "name": "ubuntuVM1-NetworkInterface", - "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "2023-04-01", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Network/publicIPAddresses', 'ubuntuVM1-PublicIP')]", - "[resourceId('Microsoft.Network/virtualNetworks', 'ubuntuVM1-VirtualNetwork')]" - ], - "tags": { - "displayName": "ubuntuVM1-NetworkInterface" - }, - "properties": { - "ipConfigurations": [ - { - "name": "ipConfig1", - "properties": { - "privateIPAllocationMethod": "Dynamic", - "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', 'ubuntuVM1-PublicIP')]" - }, - "subnet": { - "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'ubuntuVM1-VirtualNetwork', 'ubuntuVM1-VirtualNetwork-Subnet')]" - } - } - } - ] - } - }, - { - "name": "ubuntuVM1", - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2023-03-01", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Network/networkInterfaces', 'ubuntuVM1-NetworkInterface')]" - ], - "tags": { - "displayName": "ubuntuVM1" - }, - "properties": { - "hardwareProfile": { - "vmSize": "Standard_A2_v2" - }, - "osProfile": { - "computerName": "ubuntuVM1", - "adminUsername": "adminUsername", - "adminPassword": "adminPassword" - }, - "storageProfile": { - "imageReference": { - "publisher": "Canonical", - "offer": "UbuntuServer", - "sku": "16.04-LTS", - "version": "latest" - }, - "osDisk": { - "name": "ubuntuVM1-OSDisk", - "caching": "ReadWrite", - "createOption": "FromImage" - } - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[resourceId('Microsoft.Network/networkInterfaces', 'ubuntuVM1-NetworkInterface')]" - } - ] - }, - "diagnosticsProfile": { - "bootDiagnostics": { - "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', toLower('ubuntuVM1storage'))).primaryEndpoints.blob]" - } - } - } - } - ], - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "variables": { - //Insert here: variable - }, - "parameters": { - //Insert here: parameter - }, - "outputs": { - //Insert here: output - }, - "functions": [ - { - "namespace": "udf", - "members": { - //Insert here: user function - } - } - ] -} + "resources": [ + { + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2020-05-01", + "name": "[variables('networkSecurityGroupName')]", + "location": "[parameters('location')]", + "properties": { + "securityRules": [ + { + "name": "ssh_rule", + "properties": { + "description": "Locks inbound down to ssh default port 22.", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "22", + "sourceAddressPrefix": "*", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 123, + "direction": "Inbound" + } + } + ] + } + }, + { + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2020-05-01", + "name": "[variables('publicIPAddressName')]", + "location": "[parameters('location')]", + "properties": { + "publicIPAllocationMethod": "Dynamic" + }, + "sku": { + "name": "Basic" + } + }, + { + "comments": "Simple Network Security Group for subnet [variables('vNetSubnetName')]", + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2020-05-01", + "name": "[variables('networkSecurityGroupName2')]", + "location": "[parameters('location')]", + "properties": { + "securityRules": [ + { + "name": "default-allow-22", + "properties": { + "priority": 1000, + "access": "Allow", + "direction": "Inbound", + "destinationPortRange": "22", + "protocol": "Tcp", + "sourceAddressPrefix": "*", + "sourcePortRange": "*", + "destinationAddressPrefix": "*" + } + } + ] + } + }, + { + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2020-05-01", + "name": "[variables('vNetName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName2'))]" + ], + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('vNetAddressPrefixes')]" + ] + }, + "subnets": [ + { + "name": "[variables('vNetSubnetName')]", + "properties": { + "addressPrefix": "[variables('vNetSubnetAddressPrefix')]", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName2'))]" + } + } + } + ] + } + }, + { + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "2020-05-01", + "name": "[variables('networkInterfaceName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]", + "[resourceId('Microsoft.Network/virtualNetworks', variables('vNetName'))]", + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + }, + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vNetName'), variables('vNetSubnetName'))]" + } + } + } + ] + } + }, + { + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2021-11-01", + "name": "[variables('vmName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]" + ], + "properties": { + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "osProfile": { + "computerName": "[variables('vmName')]", + "adminUsername": "[parameters('adminUsername')]", + "linuxConfiguration": { + "disablePasswordAuthentication": true, + "ssh": { + "publicKeys": [ + { + "path": "[concat('/home/', parameters('adminUsername'), '/.ssh/authorized_keys')]", + "keyData": "[parameters('adminPublicKey')]" + } + ] + } + } + }, + "storageProfile": { + "imageReference": { + "publisher": "Canonical", + "offer": "0001-com-ubuntu-server-jammy", + "sku": "22_04-lts-gen2", + "version": "latest" + }, + "osDisk": { + "createOption": "fromImage" + } + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]" + } + ] + } + } + } + ], + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "variables": { + //Insert here: variable + }, + "parameters": { + "location": { + "type": "string" + } + //Insert here: parameter + }, + "outputs": { + //Insert here: output + }, + "functions": [ + { + "namespace": "udf", + "members": { + //Insert here: user function + } + } + ] +} \ No newline at end of file From 008c8596fdf838a97bebd214cfa7b7dfd874d4a9 Mon Sep 17 00:00:00 2001 From: Stephen Weatherford Date: Fri, 28 Jun 2024 13:55:51 -0700 Subject: [PATCH 02/11] Fix Update-ApiVersions.ps1 --- tools/Update-ApiVersions.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Update-ApiVersions.ps1 b/tools/Update-ApiVersions.ps1 index e00accce4..bc4bccf98 100644 --- a/tools/Update-ApiVersions.ps1 +++ b/tools/Update-ApiVersions.ps1 @@ -111,7 +111,7 @@ function Find-UsedApiVersionsInJson { foreach ($resource in $resources) { $type = $resource.type $apiVersion = $resource.apiVersion - if ($type && $apiVersion) { + if ($type -ne "" -and $apiVersion -ne "") { $uses += "$type@$apiVersion" } } From a822058cd12b06d7088ea7f6bf5c73e0c82b425e Mon Sep 17 00:00:00 2001 From: Stephen Weatherford Date: Fri, 28 Jun 2024 14:24:17 -0700 Subject: [PATCH 03/11] Add disablePasswordAuthentication in test file --- .../apiVersion-can-be-an-expression.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/templates/arm-template-language-samples/apiVersion-can-be-an-expression.json b/test/templates/arm-template-language-samples/apiVersion-can-be-an-expression.json index 5a286f6de..50a0891d4 100644 --- a/test/templates/arm-template-language-samples/apiVersion-can-be-an-expression.json +++ b/test/templates/arm-template-language-samples/apiVersion-can-be-an-expression.json @@ -508,7 +508,10 @@ "osProfile": { "adminPassword": "[variables('adminPassword')]", "adminUsername": "[variables('adminUsername')]", - "computerName": "[variables('vmName')]" + "computerName": "[variables('vmName')]", + "linuxConfiguration": { + "disablePasswordAuthentication": true + } }, "storageProfile": { "imageReference": { From 813d2aa5141c96d3bbf52ddbc784ab28f5a6a955 Mon Sep 17 00:00:00 2001 From: Stephen Weatherford Date: Fri, 28 Jun 2024 14:24:41 -0700 Subject: [PATCH 04/11] editor.formatOnSave=false --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 2a3e37229..2bcc3528d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,5 @@ { - "editor.formatOnSave": true, + "editor.formatOnSave": false, "editor.insertSpaces": true, "editor.tabSize": 4, "files.insertFinalNewline": true, From 5dc8d992d0cbe596ce69181e1a9eaf5784b059ce Mon Sep 17 00:00:00 2001 From: Stephen Weatherford Date: Fri, 28 Jun 2024 15:11:33 -0700 Subject: [PATCH 05/11] Update Windows Virtual Machine --- .../Ubuntu Virtual Machine.snippet.json | 2 +- .../Windows Virtual Machine.snippet.json | 179 ++++++++++-------- test/functional/snippets.test.ts | 43 +++++ ...Windows Virtual Machine.snippetresult.json | 167 +++++++++------- 4 files changed, 238 insertions(+), 153 deletions(-) diff --git a/assets/resourceSnippets/Ubuntu Virtual Machine.snippet.json b/assets/resourceSnippets/Ubuntu Virtual Machine.snippet.json index 6dda19db5..ca76beb5d 100644 --- a/assets/resourceSnippets/Ubuntu Virtual Machine.snippet.json +++ b/assets/resourceSnippets/Ubuntu Virtual Machine.snippet.json @@ -3,7 +3,7 @@ "contentVersion": "1.0.0.0", "metadata": { "prefix": "arm-vm-ubuntu", - "description": "Ubuntu Virtual Machine (see https://learn.microsoft.com/azure/virtual-machines/linux/create-ssh-secured-vm-from-template for more information)" + "description": "Ubuntu Virtual Machine (see https://learn.microsoft.com/azure/virtual-machines/linux/create-ssh-secured-vm-from-template)" }, "parameters": { "projectName": { diff --git a/assets/resourceSnippets/Windows Virtual Machine.snippet.json b/assets/resourceSnippets/Windows Virtual Machine.snippet.json index cc243a51a..d5440d3e7 100644 --- a/assets/resourceSnippets/Windows Virtual Machine.snippet.json +++ b/assets/resourceSnippets/Windows Virtual Machine.snippet.json @@ -3,168 +3,189 @@ "contentVersion": "1.0.0.0", "metadata": { "prefix": "arm-vm-windows", - "description": "Windows Virtual Machine" + "description": "Windows Virtual Machine (see https://learn.microsoft.com/en-us/azure/virtual-machines/windows/quick-create-template)" }, "resources": [ { - "name": "[toLower('${1:windowsVM1}storage')]", "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2023-01-01", - "location": "[resourceGroup().location]", - "tags": { - "displayName": "${1:windowsVM1} Storage Account" - }, + "apiVersion": "2022-05-01", + "name": "[variables('storageAccountName')]", + "location": "[parameters('location')]", "sku": { - "name": "${2:Standard_LRS}" + "name": "Standard_LRS" }, - "kind": /*${3|Storage,StorageV2|}*/ "Storage" + "kind": "Storage" }, { - "name": "${1:windowsVM1}-PublicIP", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "2023-04-01", - "location": "[resourceGroup().location]", - "tags": { - "displayName": "PublicIPAddress" + "apiVersion": "2022-05-01", + "name": "[parameters('publicIpName')]", + "location": "[parameters('location')]", + "sku": { + "name": "[parameters('publicIpSku')]" }, "properties": { - "publicIPAllocationMethod": "Dynamic", + "publicIPAllocationMethod": "[parameters('publicIPAllocationMethod')]", "dnsSettings": { - "domainNameLabel": "[toLower('${1:windowsVM1}')]" + "domainNameLabel": "[parameters('dnsLabelPrefix')]" } } }, { - "name": "${1:windowsVM1}-nsg", "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "2023-04-01", - "location": "[resourceGroup().location]", + "apiVersion": "2022-05-01", + "name": "[variables('networkSecurityGroupName')]", + "location": "[parameters('location')]", "properties": { "securityRules": [ { - "name": "${4:nsgRule1}", + "name": "default-allow-3389", "properties": { - "description": "${5:description}", - "protocol": /*${6|Tcp,Udp,*|}*/ "Tcp", - "sourcePortRange": "${7:*}", - "destinationPortRange": "${8:3389}", - "sourceAddressPrefix": "${9:*}", - "destinationAddressPrefix": "${10:*}", - "access": /*${11|Allow,Deny|}*/ "Allow", - "priority": /*${12:100}*/ 100, - "direction": /*${13|Inbound,Outbound|}*/ "Inbound" + "priority": 1000, + "access": "Allow", + "direction": "Inbound", + "destinationPortRange": "3389", + "protocol": "Tcp", + "sourcePortRange": "*", + "sourceAddressPrefix": "*", + "destinationAddressPrefix": "*" } } ] } }, { - "name": "${1:windowsVM1}-VirtualNetwork", "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "2023-04-01", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Network/networkSecurityGroups', '${1:windowsVM1}-nsg')]" - ], - "tags": { - "displayName": "${1:windowsVM1}-VirtualNetwork" - }, + "apiVersion": "2022-05-01", + "name": "[variables('virtualNetworkName')]", + "location": "[parameters('location')]", "properties": { "addressSpace": { "addressPrefixes": [ - "10.0.0.0/16" + "[variables('addressPrefix')]" ] }, "subnets": [ { - "name": "${1:windowsVM1}-VirtualNetwork-Subnet", + "name": "[variables('subnetName')]", "properties": { - "addressPrefix": "10.0.0.0/24", + "addressPrefix": "[variables('subnetPrefix')]", "networkSecurityGroup": { - "id": "[resourceId('Microsoft.Network/networkSecurityGroups', '${1:windowsVM1}-nsg')]" + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" } } } ] - } + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" + ] }, { - "name": "${1:windowsVM1}-NetworkInterface", "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "2023-04-01", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Network/publicIPAddresses', '${1:windowsVM1}-PublicIP')]", - "[resourceId('Microsoft.Network/virtualNetworks', '${1:windowsVM1}-VirtualNetwork')]" - ], - "tags": { - "displayName": "${1:windowsVM1} Network Interface" - }, + "apiVersion": "2022-05-01", + "name": "[variables('nicName')]", + "location": "[parameters('location')]", "properties": { "ipConfigurations": [ { - "name": "ipConfig1", + "name": "ipconfig1", "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', '${1:windowsVM1}-PublicIP')]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpName'))]" }, "subnet": { - "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', '${1:windowsVM1}-VirtualNetwork', '${1:windowsVM1}-VirtualNetwork-Subnet')]" + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetName'))]" } } } ] - } + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpName'))]", + "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + ] }, { - "name": "${1:windowsVM1}", "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2023-03-01", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', toLower('${1:windowsVM1}storage'))]", - "[resourceId('Microsoft.Network/networkInterfaces', '${1:windowsVM1}-NetworkInterface')]" - ], - "tags": { - "displayName": "${1:windowsVM1}" - }, + "apiVersion": "2022-03-01", + "name": "[parameters('vmName')]", + "location": "[parameters('location')]", "properties": { "hardwareProfile": { - "vmSize": "Standard_A2_v2" + "vmSize": "[parameters('vmSize')]" }, "osProfile": { - "computerName": "${1:windowsVM1}", - "adminUsername": "${14:adminUsername}", - "adminPassword": "${15:adminPassword}" + "computerName": "[parameters('vmName')]", + "adminUsername": "[parameters('adminUsername')]", + "adminPassword": "[parameters('adminPassword')]" }, "storageProfile": { "imageReference": { "publisher": "MicrosoftWindowsServer", "offer": "WindowsServer", - "sku": "2012-R2-Datacenter", + "sku": "[parameters('OSVersion')]", "version": "latest" }, "osDisk": { - "name": "${1:windowsVM1}OSDisk", - "caching": "ReadWrite", - "createOption": "FromImage" - } + "createOption": "FromImage", + "managedDisk": { + "storageAccountType": "StandardSSD_LRS" + } + }, + "dataDisks": [ + { + "diskSizeGB": 1023, + "lun": 0, + "createOption": "Empty" + } + ] }, "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', '${1:windowsVM1}-NetworkInterface')]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" } ] }, "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', toLower('${1:windowsVM1}storage'))).primaryEndpoints.blob]" + "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2022-05-01').primaryEndpoints.blob]" + } + }, + "securityProfile": "[if(equals(parameters('securityType'), 'TrustedLaunch'), variables('securityProfileJson'), null())]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]", + "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]" + ] + }, + { + "condition": "[and(equals(parameters('securityType'), 'TrustedLaunch'), and(equals(variables('securityProfileJson').uefiSettings.secureBootEnabled, true()), equals(variables('securityProfileJson').uefiSettings.vTpmEnabled, true())))]", + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-03-01", + "name": "[format('{0}/{1}', parameters('vmName'), variables('extensionName'))]", + "location": "[parameters('location')]", + "properties": { + "publisher": "[variables('extensionPublisher')]", + "type": "[variables('extensionName')]", + "typeHandlerVersion": "[variables('extensionVersion')]", + "autoUpgradeMinorVersion": true, + "enableAutomaticUpgrade": true, + "settings": { + "AttestationConfig": { + "MaaSettings": { + "maaEndpoint": "[variables('maaEndpoint')]", + "maaTenantName": "[variables('maaTenantName')]" + } } } - } + }, + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines', parameters('vmName'))]" + ] } ] } diff --git a/test/functional/snippets.test.ts b/test/functional/snippets.test.ts index e438e0720..e1839ab4d 100644 --- a/test/functional/snippets.test.ts +++ b/test/functional/snippets.test.ts @@ -278,6 +278,49 @@ const overrideExpectedDiagnostics: { [name: string]: (string | RegExp)[] } = { "Undefined variable reference: 'vmName'", "Undefined variable reference: 'vmName'" ], + "Windows Virtual Machine": [ + "Undefined parameter reference: 'OSVersion'", + "Undefined parameter reference: 'adminPassword'", + "Undefined parameter reference: 'adminUsername'", + "Undefined parameter reference: 'dnsLabelPrefix'", + "Undefined parameter reference: 'publicIPAllocationMethod'", + "Undefined parameter reference: 'publicIpName'", + "Undefined parameter reference: 'publicIpName'", + "Undefined parameter reference: 'publicIpName'", + "Undefined parameter reference: 'publicIpSku'", + "Undefined parameter reference: 'securityType'", + "Undefined parameter reference: 'securityType'", + "Undefined parameter reference: 'vmName'", + "Undefined parameter reference: 'vmName'", + "Undefined parameter reference: 'vmName'", + "Undefined parameter reference: 'vmName'", + "Undefined parameter reference: 'vmSize'", + "Undefined variable reference: 'addressPrefix'", + "Undefined variable reference: 'extensionName'", + "Undefined variable reference: 'extensionName'", + "Undefined variable reference: 'extensionPublisher'", + "Undefined variable reference: 'extensionVersion'", + "Undefined variable reference: 'maaEndpoint'", + "Undefined variable reference: 'maaTenantName'", + "Undefined variable reference: 'networkSecurityGroupName'", + "Undefined variable reference: 'networkSecurityGroupName'", + "Undefined variable reference: 'networkSecurityGroupName'", + "Undefined variable reference: 'nicName'", + "Undefined variable reference: 'nicName'", + "Undefined variable reference: 'nicName'", + "Undefined variable reference: 'securityProfileJson'", + "Undefined variable reference: 'securityProfileJson'", + "Undefined variable reference: 'securityProfileJson'", + "Undefined variable reference: 'storageAccountName'", + "Undefined variable reference: 'storageAccountName'", + "Undefined variable reference: 'storageAccountName'", + "Undefined variable reference: 'subnetName'", + "Undefined variable reference: 'subnetName'", + "Undefined variable reference: 'subnetPrefix'", + "Undefined variable reference: 'virtualNetworkName'", + "Undefined variable reference: 'virtualNetworkName'", + "Undefined variable reference: 'virtualNetworkName'", + ], "Windows VM Custom Script": [ // Blocked by https://github.com/Azure/azure-resource-manager-schemas/issues/995 "Missing required property \"commandToExecute\"", diff --git a/test/snippets/expected/Windows Virtual Machine.snippetresult.json b/test/snippets/expected/Windows Virtual Machine.snippetresult.json index b4b593005..cc597a4a0 100644 --- a/test/snippets/expected/Windows Virtual Machine.snippetresult.json +++ b/test/snippets/expected/Windows Virtual Machine.snippetresult.json @@ -1,164 +1,185 @@ { "resources": [ { - "name": "[toLower('windowsVM1storage')]", "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2023-01-01", - "location": "[resourceGroup().location]", - "tags": { - "displayName": "windowsVM1 Storage Account" - }, + "apiVersion": "2022-05-01", + "name": "[variables('storageAccountName')]", + "location": "[parameters('location')]", "sku": { "name": "Standard_LRS" }, "kind": "Storage" }, { - "name": "windowsVM1-PublicIP", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "2023-04-01", - "location": "[resourceGroup().location]", - "tags": { - "displayName": "PublicIPAddress" + "apiVersion": "2022-05-01", + "name": "[parameters('publicIpName')]", + "location": "[parameters('location')]", + "sku": { + "name": "[parameters('publicIpSku')]" }, "properties": { - "publicIPAllocationMethod": "Dynamic", + "publicIPAllocationMethod": "[parameters('publicIPAllocationMethod')]", "dnsSettings": { - "domainNameLabel": "[toLower('windowsVM1')]" + "domainNameLabel": "[parameters('dnsLabelPrefix')]" } } }, { - "name": "windowsVM1-nsg", "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "2023-04-01", - "location": "[resourceGroup().location]", + "apiVersion": "2022-05-01", + "name": "[variables('networkSecurityGroupName')]", + "location": "[parameters('location')]", "properties": { "securityRules": [ { - "name": "nsgRule1", + "name": "default-allow-3389", "properties": { - "description": "description", + "priority": 1000, + "access": "Allow", + "direction": "Inbound", + "destinationPortRange": "3389", "protocol": "Tcp", "sourcePortRange": "*", - "destinationPortRange": "3389", "sourceAddressPrefix": "*", - "destinationAddressPrefix": "*", - "access": "Allow", - "priority": 100, - "direction": "Inbound" + "destinationAddressPrefix": "*" } } ] } }, { - "name": "windowsVM1-VirtualNetwork", "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "2023-04-01", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Network/networkSecurityGroups', 'windowsVM1-nsg')]" - ], - "tags": { - "displayName": "windowsVM1-VirtualNetwork" - }, + "apiVersion": "2022-05-01", + "name": "[variables('virtualNetworkName')]", + "location": "[parameters('location')]", "properties": { "addressSpace": { "addressPrefixes": [ - "10.0.0.0/16" + "[variables('addressPrefix')]" ] }, "subnets": [ { - "name": "windowsVM1-VirtualNetwork-Subnet", + "name": "[variables('subnetName')]", "properties": { - "addressPrefix": "10.0.0.0/24", + "addressPrefix": "[variables('subnetPrefix')]", "networkSecurityGroup": { - "id": "[resourceId('Microsoft.Network/networkSecurityGroups', 'windowsVM1-nsg')]" + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" } } } ] - } + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" + ] }, { - "name": "windowsVM1-NetworkInterface", "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "2023-04-01", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Network/publicIPAddresses', 'windowsVM1-PublicIP')]", - "[resourceId('Microsoft.Network/virtualNetworks', 'windowsVM1-VirtualNetwork')]" - ], - "tags": { - "displayName": "windowsVM1 Network Interface" - }, + "apiVersion": "2022-05-01", + "name": "[variables('nicName')]", + "location": "[parameters('location')]", "properties": { "ipConfigurations": [ { - "name": "ipConfig1", + "name": "ipconfig1", "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', 'windowsVM1-PublicIP')]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpName'))]" }, "subnet": { - "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'windowsVM1-VirtualNetwork', 'windowsVM1-VirtualNetwork-Subnet')]" + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetName'))]" } } } ] - } + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpName'))]", + "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + ] }, { - "name": "windowsVM1", "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2023-03-01", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', toLower('windowsVM1storage'))]", - "[resourceId('Microsoft.Network/networkInterfaces', 'windowsVM1-NetworkInterface')]" - ], - "tags": { - "displayName": "windowsVM1" - }, + "apiVersion": "2022-03-01", + "name": "[parameters('vmName')]", + "location": "[parameters('location')]", "properties": { "hardwareProfile": { - "vmSize": "Standard_A2_v2" + "vmSize": "[parameters('vmSize')]" }, "osProfile": { - "computerName": "windowsVM1", - "adminUsername": "adminUsername", - "adminPassword": "adminPassword" + "computerName": "[parameters('vmName')]", + "adminUsername": "[parameters('adminUsername')]", + "adminPassword": "[parameters('adminPassword')]" }, "storageProfile": { "imageReference": { "publisher": "MicrosoftWindowsServer", "offer": "WindowsServer", - "sku": "2012-R2-Datacenter", + "sku": "[parameters('OSVersion')]", "version": "latest" }, "osDisk": { - "name": "windowsVM1OSDisk", - "caching": "ReadWrite", - "createOption": "FromImage" - } + "createOption": "FromImage", + "managedDisk": { + "storageAccountType": "StandardSSD_LRS" + } + }, + "dataDisks": [ + { + "diskSizeGB": 1023, + "lun": 0, + "createOption": "Empty" + } + ] }, "networkProfile": { "networkInterfaces": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', 'windowsVM1-NetworkInterface')]" + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" } ] }, "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', toLower('windowsVM1storage'))).primaryEndpoints.blob]" + "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2022-05-01').primaryEndpoints.blob]" + } + }, + "securityProfile": "[if(equals(parameters('securityType'), 'TrustedLaunch'), variables('securityProfileJson'), null())]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]", + "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]" + ] + }, + { + "condition": "[and(equals(parameters('securityType'), 'TrustedLaunch'), and(equals(variables('securityProfileJson').uefiSettings.secureBootEnabled, true()), equals(variables('securityProfileJson').uefiSettings.vTpmEnabled, true())))]", + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-03-01", + "name": "[format('{0}/{1}', parameters('vmName'), variables('extensionName'))]", + "location": "[parameters('location')]", + "properties": { + "publisher": "[variables('extensionPublisher')]", + "type": "[variables('extensionName')]", + "typeHandlerVersion": "[variables('extensionVersion')]", + "autoUpgradeMinorVersion": true, + "enableAutomaticUpgrade": true, + "settings": { + "AttestationConfig": { + "MaaSettings": { + "maaEndpoint": "[variables('maaEndpoint')]", + "maaTenantName": "[variables('maaTenantName')]" + } } } - } + }, + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines', parameters('vmName'))]" + ] } ], "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", From fc381aaa099da82eecbddc5c95097503fa4200ed Mon Sep 17 00:00:00 2001 From: Stephen Weatherford Date: Fri, 28 Jun 2024 15:13:48 -0700 Subject: [PATCH 06/11] Update nuget to allowed version 5.11.6 --- .azure-pipelines/common/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure-pipelines/common/build.yml b/.azure-pipelines/common/build.yml index da5a87840..8c442b7dd 100644 --- a/.azure-pipelines/common/build.yml +++ b/.azure-pipelines/common/build.yml @@ -2,12 +2,12 @@ steps: # Install nuget for use by 'npm run package' - task: NuGetToolInstaller@0 inputs: - versionSpec: "5.2.0" + versionSpec: "5.11.6" - task: NodeTool@0 displayName: "Install node.js" inputs: - versionSpec: 18.16.0 + versionSpec: 18.16.0 - script: npm install -g npm@8.19.4 displayName: "Install npm" From 1510723b1d1c71772f5a23bfdc9169a7ed46f4a1 Mon Sep 17 00:00:00 2001 From: Stephen Weatherford Date: Fri, 28 Jun 2024 15:38:29 -0700 Subject: [PATCH 07/11] fix tests --- test/functional/snippets.test.ts | 3 ++- .../expected/Windows Virtual Machine.snippetresult.json | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/test/functional/snippets.test.ts b/test/functional/snippets.test.ts index e1839ab4d..123becab0 100644 --- a/test/functional/snippets.test.ts +++ b/test/functional/snippets.test.ts @@ -30,6 +30,7 @@ import { writeToLog } from '../support/testLog'; import { UseRealSnippets } from '../support/TestSnippets'; import { RequiresLanguageServer } from '../support/testWithLanguageServer'; import { testWithPrep } from '../support/testWithPrep'; +import { UseRealFunctionMetadata } from '../TestData'; const resultsFolder = path.join(__dirname, '..', '..', '..', 'test', 'snippets', 'results'); const expectedFolder = path.join(__dirname, '..', '..', '..', 'test', 'snippets', 'expected'); @@ -365,7 +366,7 @@ suite("Snippets functional tests", () => { for (let i = 0; i < 1; ++i) { testWithPrep( `snippet: ${snippetName}`, - [RequiresLanguageServer.instance, UseRealSnippets.instance], + [RequiresLanguageServer.instance, UseRealSnippets.instance, UseRealFunctionMetadata.instance], async function (this: Context): Promise { const snippets = (await manager.getAllSnippets()); const snippet = snippets.find(s => s.name === snippetName); diff --git a/test/snippets/expected/Windows Virtual Machine.snippetresult.json b/test/snippets/expected/Windows Virtual Machine.snippetresult.json index cc597a4a0..e22703479 100644 --- a/test/snippets/expected/Windows Virtual Machine.snippetresult.json +++ b/test/snippets/expected/Windows Virtual Machine.snippetresult.json @@ -187,11 +187,11 @@ "variables": { //Insert here: variable }, + "outputs": {}, "parameters": { - //Insert here: parameter - }, - "outputs": { - //Insert here: output + "location": { + "type": "string" + } }, "functions": [ { From 797841667d76d02cef606cbd0bbc43a7e0567779 Mon Sep 17 00:00:00 2001 From: Stephen Weatherford Date: Fri, 28 Jun 2024 15:59:32 -0700 Subject: [PATCH 08/11] Update virtual network --- .../resourceSnippets/Virtual Network.snippet.json | 13 +++++++++++-- test/functional/snippets.test.ts | 3 +++ .../expected/Virtual Network.snippetresult.json | 10 ++++++++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/assets/resourceSnippets/Virtual Network.snippet.json b/assets/resourceSnippets/Virtual Network.snippet.json index b952694d6..8af2ce673 100644 --- a/assets/resourceSnippets/Virtual Network.snippet.json +++ b/assets/resourceSnippets/Virtual Network.snippet.json @@ -14,6 +14,9 @@ "tags": { "displayName": "${1:virtualNetwork1}" }, + "dependsOn": [ + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" + ], "properties": { "addressSpace": { "addressPrefixes": [ @@ -24,13 +27,19 @@ { "name": "Subnet-1", "properties": { - "addressPrefix": "10.0.0.0/24" + "addressPrefix": "10.0.0.0/24", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" + } } }, { "name": "Subnet-2", "properties": { - "addressPrefix": "10.0.1.0/24" + "addressPrefix": "10.0.1.0/24", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" + } } } ] diff --git a/test/functional/snippets.test.ts b/test/functional/snippets.test.ts index 123becab0..9dbbdb814 100644 --- a/test/functional/snippets.test.ts +++ b/test/functional/snippets.test.ts @@ -279,6 +279,9 @@ const overrideExpectedDiagnostics: { [name: string]: (string | RegExp)[] } = { "Undefined variable reference: 'vmName'", "Undefined variable reference: 'vmName'" ], + "Virtual Network": [ + "Undefined parameter reference: 'networkSecurityGroupName'", + ], "Windows Virtual Machine": [ "Undefined parameter reference: 'OSVersion'", "Undefined parameter reference: 'adminPassword'", diff --git a/test/snippets/expected/Virtual Network.snippetresult.json b/test/snippets/expected/Virtual Network.snippetresult.json index 1d3dc5f0d..bc6ea35ac 100644 --- a/test/snippets/expected/Virtual Network.snippetresult.json +++ b/test/snippets/expected/Virtual Network.snippetresult.json @@ -18,13 +18,19 @@ { "name": "Subnet-1", "properties": { - "addressPrefix": "10.0.0.0/24" + "addressPrefix": "10.0.0.0/24", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" + } } }, { "name": "Subnet-2", "properties": { - "addressPrefix": "10.0.1.0/24" + "addressPrefix": "10.0.1.0/24", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" + } } } ] From 93a44e0a7d3981d7a3ded91db58c854c1dc499c8 Mon Sep 17 00:00:00 2001 From: Stephen Weatherford Date: Fri, 28 Jun 2024 16:04:40 -0700 Subject: [PATCH 09/11] more test fixes --- .../schema-type-mismatch-bool-int.json | 11 ++++++++++- .../variables-object-use-determination.json | 9 +++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/test/templates/arm-template-language-samples/schema-type-mismatch-bool-int.json b/test/templates/arm-template-language-samples/schema-type-mismatch-bool-int.json index 39530f46b..5b7a224cb 100644 --- a/test/templates/arm-template-language-samples/schema-type-mismatch-bool-int.json +++ b/test/templates/arm-template-language-samples/schema-type-mismatch-bool-int.json @@ -60,6 +60,12 @@ "description": "The size of the Virtual Machine." } }, + "networkSecurityGroupName": { + "type": "string", + "metadata": { + "description": "Name of the Network Security Group." + }, + }, "_artifactsLocation": { "type": "string", "metadata": { @@ -262,7 +268,10 @@ "name": "[variables('virtualNetworkName')]", "properties": { "addressPrefix": "[variables('addressPrefix')]" - } + }, + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" + } } ] } diff --git a/test/templates/arm-template-language-samples/variables-object-use-determination.json b/test/templates/arm-template-language-samples/variables-object-use-determination.json index 3814d0b88..c8377a5f8 100644 --- a/test/templates/arm-template-language-samples/variables-object-use-determination.json +++ b/test/templates/arm-template-language-samples/variables-object-use-determination.json @@ -45,6 +45,12 @@ "description": "SSH RSA public key file as a string." } }, + "networkSecurityGroupName": { + "type": "string", + "metadata": { + "description": "Name of the Network Security Group." + } + }, "vmSize": { "type": "string", "defaultValue": "Standard_D4_v3", @@ -261,6 +267,9 @@ "name": "[variables('virtualNetworkName')]", "properties": { "addressPrefix": "[variables('addressPrefix')]" + }, + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" } } ] From c195ee24938b3dcca384424f47029a288e1a41e8 Mon Sep 17 00:00:00 2001 From: Stephen Weatherford Date: Fri, 28 Jun 2024 18:09:21 -0700 Subject: [PATCH 10/11] fixes --- .../Ubuntu Virtual Machine.snippet.json | 45 --- .../functional/contextualizedSnippets.test.ts | 274 +++++++++--------- test/functional/snippets.test.ts | 5 +- test/support/getEventPromise.ts | 2 +- 4 files changed, 143 insertions(+), 183 deletions(-) diff --git a/assets/resourceSnippets/Ubuntu Virtual Machine.snippet.json b/assets/resourceSnippets/Ubuntu Virtual Machine.snippet.json index ca76beb5d..2bd600ac8 100644 --- a/assets/resourceSnippets/Ubuntu Virtual Machine.snippet.json +++ b/assets/resourceSnippets/Ubuntu Virtual Machine.snippet.json @@ -5,51 +5,6 @@ "prefix": "arm-vm-ubuntu", "description": "Ubuntu Virtual Machine (see https://learn.microsoft.com/azure/virtual-machines/linux/create-ssh-secured-vm-from-template)" }, - "parameters": { - "projectName": { - "type": "string", - "metadata": { - "description": "Specifies a name for generating resource names." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Specifies the location for all resources." - } - }, - "adminUsername": { - "type": "string", - "metadata": { - "description": "Specifies a username for the Virtual Machine." - } - }, - "adminPublicKey": { - "type": "string", - "metadata": { - "description": "Specifies the SSH rsa public key file as a string. Use \"ssh-keygen -t rsa -b 2048\" to generate your SSH key pairs." - } - }, - "vmSize": { - "type": "string", - "defaultValue": "Standard_D2s_v3", - "metadata": { - "description": "description" - } - } - }, - "variables": { - "vNetName": "[concat(parameters('projectName'), '-vnet')]", - "vNetAddressPrefixes": "10.0.0.0/16", - "vNetSubnetName": "default", - "vNetSubnetAddressPrefix": "10.0.0.0/24", - "vmName": "[concat(parameters('projectName'), '-vm')]", - "publicIPAddressName": "[concat(parameters('projectName'), '-ip')]", - "networkInterfaceName": "[concat(parameters('projectName'), '-nic')]", - "networkSecurityGroupName": "[concat(parameters('projectName'), '-nsg')]", - "networkSecurityGroupName2": "[concat(variables('vNetSubnetName'), '-nsg')]" - }, "resources": [ { "type": "Microsoft.Network/networkSecurityGroups", diff --git a/test/functional/contextualizedSnippets.test.ts b/test/functional/contextualizedSnippets.test.ts index d2e650ce0..50fea83ff 100644 --- a/test/functional/contextualizedSnippets.test.ts +++ b/test/functional/contextualizedSnippets.test.ts @@ -450,164 +450,166 @@ suite("Contextualized snippets", () => { "contentVersion": "1.0.0.0", "resources": [ { - "name": "[toLower('ubuntuVM1storage')]", - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "xxxx-xx-xx", - "location": "[resourceGroup().location]", - "tags": { - "displayName": "ubuntuVM1 Storage Account" - }, - "sku": { - "name": "Standard_LRS" - }, - "kind": "Storage" + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2020-05-01", + "name": "[variables('networkSecurityGroupName')]", + "location": "[parameters('location')]", + "properties": { + "securityRules": [ + { + "name": "ssh_rule", + "properties": { + "description": "Locks inbound down to ssh default port 22.", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "22", + "sourceAddressPrefix": "*", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 123, + "direction": "Inbound" + } + } + ] + } }, { - "name": "ubuntuVM1-PublicIP", - "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "xxxx-xx-xx", - "location": "[resourceGroup().location]", - "tags": { - "displayName": "PublicIPAddress" - }, - "properties": { - "publicIPAllocationMethod": "Dynamic", - "dnsSettings": { - "domainNameLabel": "[toLower('ubuntuVM1')]" + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2020-05-01", + "name": "[variables('publicIPAddressName')]", + "location": "[parameters('location')]", + "properties": { + "publicIPAllocationMethod": "Dynamic" + }, + "sku": { + "name": "Basic" + } + }, + { + "comments": "Simple Network Security Group for subnet [variables('vNetSubnetName')]", + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2020-05-01", + "name": "[variables('networkSecurityGroupName2')]", + "location": "[parameters('location')]", + "properties": { + "securityRules": [ + { + "name": "default-allow-22", + "properties": { + "priority": 1000, + "access": "Allow", + "direction": "Inbound", + "destinationPortRange": "22", + "protocol": "Tcp", + "sourceAddressPrefix": "*", + "sourcePortRange": "*", + "destinationAddressPrefix": "*" } } + ] + } }, { - "name": "ubuntuVM1-nsg", - "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "xxxx-xx-xx", - "location": "[resourceGroup().location]", - "properties": { - "securityRules": [ - { - "name": "nsgRule1", - "properties": { - "description": "description", - "protocol": "Tcp", - "sourcePortRange": "*", - "destinationPortRange": "22", - "sourceAddressPrefix": "*", - "destinationAddressPrefix": "*", - "access": "Allow", - "priority": 100, - "direction": "Inbound" - } - } - ] + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2020-05-01", + "name": "[variables('vNetName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName2'))]" + ], + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('vNetAddressPrefixes')]" + ] + }, + "subnets": [ + { + "name": "[variables('vNetSubnetName')]", + "properties": { + "addressPrefix": "[variables('vNetSubnetAddressPrefix')]", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName2'))]" + } + } } + ] + } }, { - "name": "ubuntuVM1-VirtualNetwork", - "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "xxxx-xx-xx", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Network/networkSecurityGroups', 'ubuntuVM1-nsg')]" - ], - "tags": { - "displayName": "ubuntuVM1-VirtualNetwork" - }, - "properties": { - "addressSpace": { - "addressPrefixes": [ - "10.0.0.0/16" - ] + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "2020-05-01", + "name": "[variables('networkInterfaceName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]", + "[resourceId('Microsoft.Network/virtualNetworks', variables('vNetName'))]", + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" }, - "subnets": [ - { - "name": "ubuntuVM1-VirtualNetwork-Subnet", - "properties": { - "addressPrefix": "10.0.0.0/24", - "networkSecurityGroup": { - "id": "[resourceId('Microsoft.Network/networkSecurityGroups', 'ubuntuVM1-nsg')]" - } - } - } - ] + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vNetName'), variables('vNetSubnetName'))]" + } + } } + ] + } }, { - "name": "ubuntuVM1-NetworkInterface", - "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "xxxx-xx-xx", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Network/publicIPAddresses', 'ubuntuVM1-PublicIP')]", - "[resourceId('Microsoft.Network/virtualNetworks', 'ubuntuVM1-VirtualNetwork')]" - ], - "tags": { - "displayName": "ubuntuVM1-NetworkInterface" + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2021-11-01", + "name": "[variables('vmName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]" + ], + "properties": { + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" }, - "properties": { - "ipConfigurations": [ + "osProfile": { + "computerName": "[variables('vmName')]", + "adminUsername": "[parameters('adminUsername')]", + "linuxConfiguration": { + "disablePasswordAuthentication": true, + "ssh": { + "publicKeys": [ { - "name": "ipConfig1", - "properties": { - "privateIPAllocationMethod": "Dynamic", - "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', 'ubuntuVM1-PublicIP')]" - }, - "subnet": { - "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'ubuntuVM1-VirtualNetwork', 'ubuntuVM1-VirtualNetwork-Subnet')]" - } - } + "path": "[concat('/home/', parameters('adminUsername'), '/.ssh/authorized_keys')]", + "keyData": "[parameters('adminPublicKey')]" } ] + } } - }, - { - "name": "ubuntuVM1", - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "xxxx-xx-xx", - "location": "[resourceGroup().location]", - "dependsOn": [ - "[resourceId('Microsoft.Network/networkInterfaces', 'ubuntuVM1-NetworkInterface')]" - ], - "tags": { - "displayName": "ubuntuVM1" }, - "properties": { - "hardwareProfile": { - "vmSize": "Standard_A2_v2" - }, - "osProfile": { - "computerName": "ubuntuVM1", - "adminUsername": "adminUsername", - "adminPassword": "adminPassword" - }, - "storageProfile": { - "imageReference": { - "publisher": "Canonical", - "offer": "UbuntuServer", - "sku": "16.04-LTS", - "version": "latest" - }, - "osDisk": { - "name": "ubuntuVM1-OSDisk", - "caching": "ReadWrite", - "createOption": "FromImage" - } - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[resourceId('Microsoft.Network/networkInterfaces', 'ubuntuVM1-NetworkInterface')]" - } - ] - }, - "diagnosticsProfile": { - "bootDiagnostics": { - "enabled": true, - "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', toLower('ubuntuVM1storage'))).primaryEndpoints.blob]" - } + "storageProfile": { + "imageReference": { + "publisher": "Canonical", + "offer": "0001-com-ubuntu-server-jammy", + "sku": "22_04-lts-gen2", + "version": "latest" + }, + "osDisk": { + "createOption": "fromImage" + } + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]" } + ] } } + } ] }`, [ diff --git a/test/functional/snippets.test.ts b/test/functional/snippets.test.ts index 9dbbdb814..d3c832afa 100644 --- a/test/functional/snippets.test.ts +++ b/test/functional/snippets.test.ts @@ -280,7 +280,10 @@ const overrideExpectedDiagnostics: { [name: string]: (string | RegExp)[] } = { "Undefined variable reference: 'vmName'" ], "Virtual Network": [ - "Undefined parameter reference: 'networkSecurityGroupName'", + "Template validation failed: The template variable 'networkSecurityGroupName' is not found. Please see https://aka.ms/arm-template/#variables for usage details.", + "Undefined variable reference: 'networkSecurityGroupName'", + "Undefined variable reference: 'networkSecurityGroupName'", + "Undefined variable reference: 'networkSecurityGroupName'", ], "Windows Virtual Machine": [ "Undefined parameter reference: 'OSVersion'", diff --git a/test/support/getEventPromise.ts b/test/support/getEventPromise.ts index 60944becf..0b1163261 100644 --- a/test/support/getEventPromise.ts +++ b/test/support/getEventPromise.ts @@ -10,7 +10,7 @@ import { CompletionItem, TextDocument, workspace } from 'vscode'; import { ext, ICompletionsSpyResult } from '../../extension.bundle'; import { delay } from '../support/delay'; -const defaultTimeout: number = 30 * 1000; +const defaultTimeout: number = 200 * 1000; export function getEventPromise( eventName: string, From a20640b1a1207caa93242a56da7e97b3698c6716 Mon Sep 17 00:00:00 2001 From: Stephen Weatherford Date: Fri, 28 Jun 2024 19:46:31 -0700 Subject: [PATCH 11/11] more fixes --- .../functional/contextualizedSnippets.test.ts | 190 +++++++++++------- .../Virtual Network.snippetresult.json | 3 + ...Windows Virtual Machine.snippetresult.json | 4 +- 3 files changed, 126 insertions(+), 71 deletions(-) diff --git a/test/functional/contextualizedSnippets.test.ts b/test/functional/contextualizedSnippets.test.ts index 50fea83ff..68836862b 100644 --- a/test/functional/contextualizedSnippets.test.ts +++ b/test/functional/contextualizedSnippets.test.ts @@ -19,6 +19,7 @@ import { diagnosticSources, getDiagnosticsForDocument, IGetDiagnosticsOptions } import { formatDocumentAndWait } from '../support/formatDocumentAndWait'; import { parseTemplateWithMarkers } from '../support/parseTemplate'; import { removeApiVersions } from '../support/removeApiVersions'; +import { removeComments } from '../support/removeComments'; import { simulateCompletion } from '../support/simulateCompletion'; import { TempDocument, TempEditor, TempFile } from '../support/TempFile'; import { writeToLog } from '../support/testLog'; @@ -109,10 +110,13 @@ suite("Contextualized snippets", () => { expectedTemplate = removeApiVersions(expectedTemplate); docTextAfterInsertion = removeApiVersions(docTextAfterInsertion); - assert.strictEqual(docTextAfterInsertion, expectedTemplate); + // Compare text without spaces by converting to/from JSON + const expectedNormalized = JSON.stringify(JSON.parse(removeComments(expectedTemplate)), null, 2); + const actualNormalized = JSON.stringify(JSON.parse(removeComments(docTextAfterInsertion)), null, 2); - // Compare diagnostics + assertEx.strictEqual(actualNormalized, expectedNormalized, "Doc after snippet insertion doesn't match expected"); + // Compare diagnostics assertEx.arraysEqual(messages, expectedDiagnostics, {}, "Diagnostics comparison failed"); } finally { await tempEditor?.dispose(); @@ -435,12 +439,37 @@ suite("Contextualized snippets", () => { ); createContextualizedSnippetTest( - "top-level - multiple resources in one snippet", + "top-level - multiple resources in one snippet (Ubuntu VM)", "arm-vm-ubuntu", [undefined, '{'], `{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", + "parameters": { + "adminPublicKey": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "location": { + "type": "string" + }, + "vmSize": { + "type": "string" + } + }, + "variables": { + "networkInterfaceName": "value", + "networkSecurityGroupName": "value", + "networkSecurityGroupName2": "value", + "publicIPAddressName": "value", + "vNetAddressPrefixes": "value", + "vNetName": "value", + "vNetSubnetAddressPrefix": "value", + "vNetSubnetName": "value", + "vmName": "value" + }, "resources": [ ] @@ -448,17 +477,42 @@ suite("Contextualized snippets", () => { `{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", + "parameters": { + "adminPublicKey": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "location": { + "type": "string" + }, + "vmSize": { + "type": "string" + } + }, + "variables": { + "networkInterfaceName": "value", + "networkSecurityGroupName": "value", + "networkSecurityGroupName2": "value", + "publicIPAddressName": "value", + "vNetAddressPrefixes": "value", + "vNetName": "value", + "vNetSubnetAddressPrefix": "value", + "vNetSubnetName": "value", + "vmName": "value" + }, "resources": [ - { + { "type": "Microsoft.Network/networkSecurityGroups", "apiVersion": "2020-05-01", "name": "[variables('networkSecurityGroupName')]", "location": "[parameters('location')]", "properties": { - "securityRules": [ + "securityRules": [ { - "name": "ssh_rule", - "properties": { + "name": "ssh_rule", + "properties": { "description": "Locks inbound down to ssh default port 22.", "protocol": "Tcp", "sourcePortRange": "*", @@ -468,34 +522,34 @@ suite("Contextualized snippets", () => { "access": "Allow", "priority": 123, "direction": "Inbound" - } + } } - ] + ] } - }, - { + }, + { "type": "Microsoft.Network/publicIPAddresses", "apiVersion": "2020-05-01", "name": "[variables('publicIPAddressName')]", "location": "[parameters('location')]", "properties": { - "publicIPAllocationMethod": "Dynamic" + "publicIPAllocationMethod": "Dynamic" }, "sku": { - "name": "Basic" + "name": "Basic" } - }, - { + }, + { "comments": "Simple Network Security Group for subnet [variables('vNetSubnetName')]", "type": "Microsoft.Network/networkSecurityGroups", "apiVersion": "2020-05-01", "name": "[variables('networkSecurityGroupName2')]", "location": "[parameters('location')]", "properties": { - "securityRules": [ + "securityRules": [ { - "name": "default-allow-22", - "properties": { + "name": "default-allow-22", + "properties": { "priority": 1000, "access": "Allow", "direction": "Inbound", @@ -504,112 +558,112 @@ suite("Contextualized snippets", () => { "sourceAddressPrefix": "*", "sourcePortRange": "*", "destinationAddressPrefix": "*" - } + } } - ] + ] } - }, - { + }, + { "type": "Microsoft.Network/virtualNetworks", "apiVersion": "2020-05-01", "name": "[variables('vNetName')]", "location": "[parameters('location')]", "dependsOn": [ - "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName2'))]" + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName2'))]" ], "properties": { - "addressSpace": { + "addressSpace": { "addressPrefixes": [ - "[variables('vNetAddressPrefixes')]" + "[variables('vNetAddressPrefixes')]" ] - }, - "subnets": [ + }, + "subnets": [ { - "name": "[variables('vNetSubnetName')]", - "properties": { + "name": "[variables('vNetSubnetName')]", + "properties": { "addressPrefix": "[variables('vNetSubnetAddressPrefix')]", "networkSecurityGroup": { - "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName2'))]" - } + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName2'))]" } + } } - ] + ] } - }, - { + }, + { "type": "Microsoft.Network/networkInterfaces", "apiVersion": "2020-05-01", "name": "[variables('networkInterfaceName')]", "location": "[parameters('location')]", "dependsOn": [ - "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]", - "[resourceId('Microsoft.Network/virtualNetworks', variables('vNetName'))]", - "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" + "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]", + "[resourceId('Microsoft.Network/virtualNetworks', variables('vNetName'))]", + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" ], "properties": { - "ipConfigurations": [ + "ipConfigurations": [ { - "name": "ipconfig1", - "properties": { + "name": "ipconfig1", + "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" }, "subnet": { - "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vNetName'), variables('vNetSubnetName'))]" - } + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vNetName'), variables('vNetSubnetName'))]" } + } } - ] + ] } - }, - { + }, + { "type": "Microsoft.Compute/virtualMachines", "apiVersion": "2021-11-01", "name": "[variables('vmName')]", "location": "[parameters('location')]", "dependsOn": [ - "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]" + "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]" ], "properties": { - "hardwareProfile": { + "hardwareProfile": { "vmSize": "[parameters('vmSize')]" - }, - "osProfile": { + }, + "osProfile": { "computerName": "[variables('vmName')]", "adminUsername": "[parameters('adminUsername')]", "linuxConfiguration": { - "disablePasswordAuthentication": true, - "ssh": { + "disablePasswordAuthentication": true, + "ssh": { "publicKeys": [ - { + { "path": "[concat('/home/', parameters('adminUsername'), '/.ssh/authorized_keys')]", "keyData": "[parameters('adminPublicKey')]" - } + } ] - } + } } - }, - "storageProfile": { + }, + "storageProfile": { "imageReference": { - "publisher": "Canonical", - "offer": "0001-com-ubuntu-server-jammy", - "sku": "22_04-lts-gen2", - "version": "latest" + "publisher": "Canonical", + "offer": "0001-com-ubuntu-server-jammy", + "sku": "22_04-lts-gen2", + "version": "latest" }, "osDisk": { - "createOption": "fromImage" + "createOption": "fromImage" } - }, - "networkProfile": { + }, + "networkProfile": { "networkInterfaces": [ - { + { "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]" - } + } ] - } - } + } } + } ] }`, [ diff --git a/test/snippets/expected/Virtual Network.snippetresult.json b/test/snippets/expected/Virtual Network.snippetresult.json index bc6ea35ac..f9da57cb8 100644 --- a/test/snippets/expected/Virtual Network.snippetresult.json +++ b/test/snippets/expected/Virtual Network.snippetresult.json @@ -8,6 +8,9 @@ "tags": { "displayName": "virtualNetwork1" }, + "dependsOn": [ + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" + ], "properties": { "addressSpace": { "addressPrefixes": [ diff --git a/test/snippets/expected/Windows Virtual Machine.snippetresult.json b/test/snippets/expected/Windows Virtual Machine.snippetresult.json index e22703479..4788e6a80 100644 --- a/test/snippets/expected/Windows Virtual Machine.snippetresult.json +++ b/test/snippets/expected/Windows Virtual Machine.snippetresult.json @@ -185,19 +185,17 @@ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "variables": { - //Insert here: variable }, - "outputs": {}, "parameters": { "location": { "type": "string" } }, + "outputs": {}, "functions": [ { "namespace": "udf", "members": { - //Insert here: user function } } ]