diff --git a/checkov/arm/checks/resource/VMScaleSetsAutoOSImagePatchingEnabled.py b/checkov/arm/checks/resource/VMScaleSetsAutoOSImagePatchingEnabled.py new file mode 100644 index 00000000000..53e35feb4bc --- /dev/null +++ b/checkov/arm/checks/resource/VMScaleSetsAutoOSImagePatchingEnabled.py @@ -0,0 +1,42 @@ +from __future__ import annotations + +from typing import Any + +from checkov.common.models.enums import CheckCategories, CheckResult +from checkov.arm.base_resource_check import BaseResourceCheck +from checkov.common.util.data_structures_utils import find_in_dict + + +class VMScaleSetsAutoOSImagePatchingEnabled(BaseResourceCheck): + def __init__(self) -> None: + name = "Ensure that automatic OS image patching is enabled for Virtual Machine Scale Sets" + id = "CKV_AZURE_95" + supported_resources = ("Microsoft.Compute/virtualMachineScaleSets",) + categories = (CheckCategories.GENERAL_SECURITY,) + super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources) + + def scan_resource_conf(self, conf: dict[str, Any]) -> CheckResult: + properties = conf.get("properties") + if properties and isinstance(properties, dict): + if properties.get("orchestrationMode") == "Flexible": + self.evaluated_keys = ["properties/orchestrationMode"] + return CheckResult.FAILED + + self.evaluated_keys = ["properties/virtualMachineProfile/extensionProfile/extensions"] + extensions = find_in_dict( + input_dict=properties, + key_path="virtualMachineProfile/extensionProfile/extensions", + ) + if extensions: + for extension in extensions: + extension_properties = extension.get("properties") + if extension_properties and isinstance(extension_properties, dict): + if extension_properties.get("enableAutomaticUpgrade") is True: + return CheckResult.PASSED + + return CheckResult.FAILED + + return CheckResult.UNKNOWN + + +check = VMScaleSetsAutoOSImagePatchingEnabled() diff --git a/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/fail-windows.json b/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/fail-windows.json new file mode 100644 index 00000000000..8a989b4e0dd --- /dev/null +++ b/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/fail-windows.json @@ -0,0 +1,231 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string" + }, + "osDiskType": { + "type": "string" + }, + "addressPrefixes": { + "type": "array" + }, + "subnets": { + "type": "array" + }, + "virtualNetworkId": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, + "networkSecurityGroups": { + "type": "array" + }, + "networkInterfaceConfigurations": { + "type": "array" + }, + "vmName": { + "type": "string" + }, + "virtualMachineScaleSetName": { + "type": "string" + }, + "singlePlacementGroup": { + "type": "string" + }, + "instanceCount": { + "type": "string" + }, + "instanceSize": { + "type": "string" + }, + "scaleInPolicy": { + "type": "object" + }, + "overprovision": { + "type": "bool" + }, + "upgradePolicy": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "adminPassword": { + "type": "secureString" + }, + "securityType": { + "type": "string" + }, + "secureBoot": { + "type": "bool" + }, + "vTPM": { + "type": "bool" + }, + "platformFaultDomainCount": { + "type": "string" + } + }, + "variables": { + "storageApiVersion": "2021-01-01", + "virtualMachineScaleSetApiVersion": "2023-03-01", + "namingInfix": "[toLower(substring(concat(parameters('virtualMachineScaleSetName'), uniqueString(resourceGroup().id)), 0, 9))]" + }, + "resources": [ + { + "name": "[parameters('virtualNetworkName')]", + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2021-05-01", + "location": "[parameters('location')]", + "properties": { + "addressSpace": { + "addressPrefixes": "[parameters('addressPrefixes')]" + }, + "subnets": "[parameters('subnets')]" + } + }, + { + "name": "[parameters('networkSecurityGroups')[copyIndex()].name]", + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2019-02-01", + "location": "[parameters('location')]", + "properties": { + "securityRules": "[parameters('networkSecurityGroups')[copyIndex()].rules]" + }, + "copy": { + "name": "networkSecurityGroups", + "count": "[length(parameters('networkSecurityGroups'))]" + } + }, + { + "name": "fail-windows", + "type": "Microsoft.Compute/virtualMachineScaleSets", + "apiVersion": "[variables('virtualMachineScaleSetApiVersion')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]", + "networkSecurityGroups", + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]" + ], + "properties": { + "singlePlacementGroup": "[parameters('singlePlacementGroup')]", + "virtualMachineProfile": { + "storageProfile": { + "osDisk": { + "createOption": "fromImage", + "caching": "ReadWrite", + "managedDisk": { + "storageAccountType": "[parameters('osDiskType')]" + } + }, + "imageReference": { + "publisher": "MicrosoftWindowsServer", + "offer": "WindowsServer", + "sku": "2019-datacenter-gensecond", + "version": "latest" + } + }, + "networkProfile": { + "copy": [ + { + "name": "networkInterfaceConfigurations", + "count": "[length(parameters('networkInterfaceConfigurations'))]", + "input": { + "name": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].name]", + "properties": { + "primary": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].primary]", + "enableAcceleratedNetworking": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].enableAcceleratedNetworking]", + "ipConfigurations": [ + { + "name": "[concat(take(parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].name, sub(80, length('-defaultIpConfiguration'))), '-defaultIpConfiguration')]", + "properties": { + "subnet": { + "id": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].subnetId]" + }, + "primary": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].primary]", + "applicationGatewayBackendAddressPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].applicationGatewayBackendAddressPools]", + "loadBalancerBackendAddressPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].loadBalancerBackendAddressPools]", + "publicIPAddressConfiguration": "[if( equals( parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].pipName, ''), json('null'), union(json(concat('{\"name\": \"', parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].pipName, '\"}'))\n ,json('{\"properties\": { \"idleTimeoutInMinutes\": 15}}')))]", + "loadBalancerInboundNatPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].loadBalancerInboundNatPools]" + } + } + ], + "networkSecurityGroup": "[if( equals( parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].nsgId, ''), json('null'),json(concat('{\"id\": \"', parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].nsgId, '\"}')))]" + } + } + } + ] + }, + "extensionProfile": { + "extensions": [ + { + "name": "GuestAttestation", + "properties": { + "publisher": "Microsoft.Azure.Security.WindowsAttestation", + "type": "GuestAttestation", + "typeHandlerVersion": "1.0", + "autoUpgradeMinorVersion": true, + "enableAutomaticUpgrade": false, + "settings": { + "AttestationConfig": { + "MaaSettings": { + "maaEndpoint": "", + "maaTenantName": "GuestAttestation" + }, + "AscSettings": { + "ascReportingEndpoint": "", + "ascReportingFrequency": "" + }, + "useCustomToken": "false", + "disableAlerts": "false" + } + } + } + } + ] + }, + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": true + } + }, + "osProfile": { + "computerNamePrefix": "[variables('namingInfix')]", + "adminUsername": "[parameters('adminUsername')]", + "adminPassword": "[parameters('adminPassword')]", + "windowsConfiguration": { + "provisionVmAgent": true + } + }, + "securityProfile": { + "securityType": "[parameters('securityType')]", + "uefiSettings": { + "secureBootEnabled": "[parameters('secureBoot')]", + "vTpmEnabled": "[parameters('vTPM')]" + } + } + }, + "orchestrationMode": "Uniform", + "scaleInPolicy": "[parameters('scaleInPolicy')]", + "overprovision": "[parameters('overprovision')]", + "upgradePolicy": { + "mode": "[parameters('upgradePolicy')]" + }, + "platformFaultDomainCount": "[parameters('platformFaultDomainCount')]" + }, + "sku": { + "name": "[parameters('instanceSize')]", + "capacity": "[int(parameters('instanceCount'))]" + } + } + ], + "outputs": { + "adminUsername": { + "type": "string", + "value": "[parameters('adminUsername')]" + } + } +} \ No newline at end of file diff --git a/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/fail-windows2.json b/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/fail-windows2.json new file mode 100644 index 00000000000..5396e5fa74b --- /dev/null +++ b/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/fail-windows2.json @@ -0,0 +1,225 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string" + }, + "osDiskType": { + "type": "string" + }, + "addressPrefixes": { + "type": "array" + }, + "subnets": { + "type": "array" + }, + "virtualNetworkId": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, + "networkSecurityGroups": { + "type": "array" + }, + "networkInterfaceConfigurations": { + "type": "array" + }, + "vmName": { + "type": "string" + }, + "virtualMachineScaleSetName": { + "type": "string" + }, + "instanceCount": { + "type": "string" + }, + "instanceSize": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "adminPassword": { + "type": "secureString" + }, + "patchMode": { + "type": "string" + }, + "enableHotpatching": { + "type": "bool" + }, + "securityType": { + "type": "string" + }, + "secureBoot": { + "type": "bool" + }, + "vTPM": { + "type": "bool" + }, + "platformFaultDomainCount": { + "type": "string" + } + }, + "variables": { + "storageApiVersion": "2021-01-01", + "networkApiVersion": "2020-11-01", + "virtualMachineScaleSetApiVersion": "2023-03-01", + "namingInfix": "[toLower(substring(concat(parameters('virtualMachineScaleSetName'), uniqueString(resourceGroup().id)), 0, 9))]" + }, + "resources": [ + { + "name": "[parameters('virtualNetworkName')]", + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2021-05-01", + "location": "[parameters('location')]", + "properties": { + "addressSpace": { + "addressPrefixes": "[parameters('addressPrefixes')]" + }, + "subnets": "[parameters('subnets')]" + } + }, + { + "name": "[parameters('networkSecurityGroups')[copyIndex()].name]", + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2019-02-01", + "location": "[parameters('location')]", + "properties": { + "securityRules": "[parameters('networkSecurityGroups')[copyIndex()].rules]" + }, + "copy": { + "name": "networkSecurityGroups", + "count": "[length(parameters('networkSecurityGroups'))]" + } + }, + { + "name": "fail-windows2", + "type": "Microsoft.Compute/virtualMachineScaleSets", + "apiVersion": "[variables('virtualMachineScaleSetApiVersion')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]", + "networkSecurityGroups", + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]" + ], + "properties": { + "virtualMachineProfile": { + "storageProfile": { + "osDisk": { + "createOption": "fromImage", + "caching": "ReadWrite", + "managedDisk": { + "storageAccountType": "[parameters('osDiskType')]" + } + }, + "imageReference": { + "publisher": "MicrosoftWindowsServer", + "offer": "WindowsServer", + "sku": "2019-datacenter-gensecond", + "version": "latest" + } + }, + "networkProfile": { + "networkApiVersion": "[variables('networkApiVersion')]", + "copy": [ + { + "name": "networkInterfaceConfigurations", + "count": "[length(parameters('networkInterfaceConfigurations'))]", + "input": { + "name": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].name]", + "properties": { + "primary": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].primary]", + "enableAcceleratedNetworking": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].enableAcceleratedNetworking]", + "ipConfigurations": [ + { + "name": "[concat(take(parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].name, sub(80, length('-defaultIpConfiguration'))), '-defaultIpConfiguration')]", + "properties": { + "subnet": { + "id": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].subnetId]" + }, + "primary": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].primary]", + "applicationGatewayBackendAddressPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].applicationGatewayBackendAddressPools]", + "loadBalancerBackendAddressPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].loadBalancerBackendAddressPools]", + "publicIPAddressConfiguration": "[if( equals( parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].pipName, ''), json('null'), union(json(concat('{\"name\": \"', parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].pipName, '\"}'))\n ,json('{\"properties\": { \"idleTimeoutInMinutes\": 15}}')))]" + } + } + ], + "networkSecurityGroup": "[if( equals( parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].nsgId, ''), json('null'),json(concat('{\"id\": \"', parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].nsgId, '\"}')))]" + } + } + } + ] + }, + "extensionProfile": { + "extensions": [ + { + "name": "GuestAttestation", + "properties": { + "publisher": "Microsoft.Azure.Security.WindowsAttestation", + "type": "GuestAttestation", + "typeHandlerVersion": "1.0", + "autoUpgradeMinorVersion": true, + "enableAutomaticUpgrade": true, + "settings": { + "AttestationConfig": { + "MaaSettings": { + "maaEndpoint": "", + "maaTenantName": "GuestAttestation" + }, + "AscSettings": { + "ascReportingEndpoint": "", + "ascReportingFrequency": "" + }, + "useCustomToken": "false", + "disableAlerts": "false" + } + } + } + } + ] + }, + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": true + } + }, + "osProfile": { + "computerNamePrefix": "[variables('namingInfix')]", + "adminUsername": "[parameters('adminUsername')]", + "adminPassword": "[parameters('adminPassword')]", + "windowsConfiguration": { + "provisionVmAgent": true, + "enableAutomaticUpdates": true, + "patchSettings": { + "enableHotpatching": "[parameters('enableHotpatching')]", + "patchMode": "[parameters('patchMode')]" + } + } + }, + "securityProfile": { + "securityType": "[parameters('securityType')]", + "uefiSettings": { + "secureBootEnabled": "[parameters('secureBoot')]", + "vTpmEnabled": "[parameters('vTPM')]" + } + } + }, + "orchestrationMode": "Flexible", + "platformFaultDomainCount": "[parameters('platformFaultDomainCount')]" + }, + "sku": { + "name": "[parameters('instanceSize')]", + "capacity": "[int(parameters('instanceCount'))]" + } + } + ], + "outputs": { + "adminUsername": { + "type": "string", + "value": "[parameters('adminUsername')]" + } + } +} \ No newline at end of file diff --git a/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/fail.json b/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/fail.json new file mode 100644 index 00000000000..79a393ebabf --- /dev/null +++ b/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/fail.json @@ -0,0 +1,227 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string" + }, + "osDiskType": { + "type": "string" + }, + "addressPrefixes": { + "type": "array" + }, + "subnets": { + "type": "array" + }, + "virtualNetworkId": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, + "networkSecurityGroups": { + "type": "array" + }, + "networkInterfaceConfigurations": { + "type": "array" + }, + "vmName": { + "type": "string" + }, + "virtualMachineScaleSetName": { + "type": "string" + }, + "singlePlacementGroup": { + "type": "string" + }, + "instanceCount": { + "type": "string" + }, + "instanceSize": { + "type": "string" + }, + "scaleInPolicy": { + "type": "object" + }, + "overprovision": { + "type": "bool" + }, + "upgradePolicy": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "securityType": { + "type": "string" + }, + "secureBoot": { + "type": "bool" + }, + "vTPM": { + "type": "bool" + }, + "platformFaultDomainCount": { + "type": "string" + } + }, + "variables": { + "storageApiVersion": "2021-01-01", + "virtualMachineScaleSetApiVersion": "2023-03-01", + "namingInfix": "[toLower(substring(concat(parameters('virtualMachineScaleSetName'), uniqueString(resourceGroup().id)), 0, 9))]" + }, + "resources": [ + { + "name": "[parameters('virtualNetworkName')]", + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2021-05-01", + "location": "[parameters('location')]", + "properties": { + "addressSpace": { + "addressPrefixes": "[parameters('addressPrefixes')]" + }, + "subnets": "[parameters('subnets')]" + } + }, + { + "name": "[parameters('networkSecurityGroups')[copyIndex()].name]", + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2019-02-01", + "location": "[parameters('location')]", + "properties": { + "securityRules": "[parameters('networkSecurityGroups')[copyIndex()].rules]" + }, + "copy": { + "name": "networkSecurityGroups", + "count": "[length(parameters('networkSecurityGroups'))]" + } + }, + { + "name": "fail", + "type": "Microsoft.Compute/virtualMachineScaleSets", + "apiVersion": "[variables('virtualMachineScaleSetApiVersion')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]", + "networkSecurityGroups", + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]" + ], + "properties": { + "singlePlacementGroup": "[parameters('singlePlacementGroup')]", + "virtualMachineProfile": { + "storageProfile": { + "osDisk": { + "createOption": "fromImage", + "caching": "ReadWrite", + "managedDisk": { + "storageAccountType": "[parameters('osDiskType')]" + } + }, + "imageReference": { + "publisher": "canonical", + "offer": "0001-com-ubuntu-server-focal", + "sku": "20_04-lts-gen2", + "version": "latest" + } + }, + "networkProfile": { + "copy": [ + { + "name": "networkInterfaceConfigurations", + "count": "[length(parameters('networkInterfaceConfigurations'))]", + "input": { + "name": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].name]", + "properties": { + "primary": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].primary]", + "enableAcceleratedNetworking": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].enableAcceleratedNetworking]", + "ipConfigurations": [ + { + "name": "[concat(take(parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].name, sub(80, length('-defaultIpConfiguration'))), '-defaultIpConfiguration')]", + "properties": { + "subnet": { + "id": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].subnetId]" + }, + "primary": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].primary]", + "applicationGatewayBackendAddressPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].applicationGatewayBackendAddressPools]", + "loadBalancerBackendAddressPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].loadBalancerBackendAddressPools]", + "publicIPAddressConfiguration": "[if( equals( parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].pipName, ''), json('null'), union(json(concat('{\"name\": \"', parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].pipName, '\"}'))\n ,json('{\"properties\": { \"idleTimeoutInMinutes\": 15}}')))]", + "loadBalancerInboundNatPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].loadBalancerInboundNatPools]" + } + } + ], + "networkSecurityGroup": "[if( equals( parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].nsgId, ''), json('null'),json(concat('{\"id\": \"', parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].nsgId, '\"}')))]" + } + } + } + ] + }, + "extensionProfile": { + "extensions": [ + { + "name": "GuestAttestation", + "properties": { + "publisher": "Microsoft.Azure.Security.LinuxAttestation", + "type": "GuestAttestation", + "typeHandlerVersion": "1.0", + "autoUpgradeMinorVersion": true, + "enableAutomaticUpgrade": false, + "settings": { + "AttestationConfig": { + "MaaSettings": { + "maaEndpoint": "", + "maaTenantName": "GuestAttestation" + }, + "AscSettings": { + "ascReportingEndpoint": "", + "ascReportingFrequency": "" + }, + "useCustomToken": "false", + "disableAlerts": "false" + } + } + } + } + ] + }, + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": true + } + }, + "osProfile": { + "computerNamePrefix": "[variables('namingInfix')]", + "adminUsername": "[parameters('adminUsername')]", + "linuxConfiguration": { + "disablePasswordAuthentication": true + } + }, + "securityProfile": { + "securityType": "[parameters('securityType')]", + "uefiSettings": { + "secureBootEnabled": "[parameters('secureBoot')]", + "vTpmEnabled": "[parameters('vTPM')]" + } + } + }, + "orchestrationMode": "Uniform", + "scaleInPolicy": "[parameters('scaleInPolicy')]", + "overprovision": "[parameters('overprovision')]", + "upgradePolicy": { + "mode": "[parameters('upgradePolicy')]" + }, + "platformFaultDomainCount": "[parameters('platformFaultDomainCount')]" + }, + "sku": { + "name": "[parameters('instanceSize')]", + "capacity": "[int(parameters('instanceCount'))]" + } + } + ], + "outputs": { + "adminUsername": { + "type": "string", + "value": "[parameters('adminUsername')]" + } + } +} \ No newline at end of file diff --git a/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/fail2.json b/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/fail2.json new file mode 100644 index 00000000000..fab90d564f8 --- /dev/null +++ b/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/fail2.json @@ -0,0 +1,210 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string" + }, + "osDiskType": { + "type": "string" + }, + "addressPrefixes": { + "type": "array" + }, + "subnets": { + "type": "array" + }, + "virtualNetworkId": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, + "networkSecurityGroups": { + "type": "array" + }, + "networkInterfaceConfigurations": { + "type": "array" + }, + "vmName": { + "type": "string" + }, + "virtualMachineScaleSetName": { + "type": "string" + }, + "instanceCount": { + "type": "string" + }, + "instanceSize": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "securityType": { + "type": "string" + }, + "secureBoot": { + "type": "bool" + }, + "vTPM": { + "type": "bool" + }, + "platformFaultDomainCount": { + "type": "string" + } + }, + "variables": { + "storageApiVersion": "2021-01-01", + "networkApiVersion": "2020-11-01", + "virtualMachineScaleSetApiVersion": "2023-03-01", + "namingInfix": "[toLower(substring(concat(parameters('virtualMachineScaleSetName'), uniqueString(resourceGroup().id)), 0, 9))]" + }, + "resources": [ + { + "name": "[parameters('virtualNetworkName')]", + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2021-05-01", + "location": "[parameters('location')]", + "properties": { + "addressSpace": { + "addressPrefixes": "[parameters('addressPrefixes')]" + }, + "subnets": "[parameters('subnets')]" + } + }, + { + "name": "[parameters('networkSecurityGroups')[copyIndex()].name]", + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2019-02-01", + "location": "[parameters('location')]", + "properties": { + "securityRules": "[parameters('networkSecurityGroups')[copyIndex()].rules]" + }, + "copy": { + "name": "networkSecurityGroups", + "count": "[length(parameters('networkSecurityGroups'))]" + } + }, + { + "name": "fail2", + "type": "Microsoft.Compute/virtualMachineScaleSets", + "apiVersion": "[variables('virtualMachineScaleSetApiVersion')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]", + "networkSecurityGroups", + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]" + ], + "properties": { + "virtualMachineProfile": { + "storageProfile": { + "osDisk": { + "createOption": "fromImage", + "caching": "ReadWrite", + "managedDisk": { + "storageAccountType": "[parameters('osDiskType')]" + } + }, + "imageReference": { + "publisher": "canonical", + "offer": "0001-com-ubuntu-server-focal", + "sku": "20_04-lts-gen2", + "version": "latest" + } + }, + "networkProfile": { + "networkApiVersion": "[variables('networkApiVersion')]", + "copy": [ + { + "name": "networkInterfaceConfigurations", + "count": "[length(parameters('networkInterfaceConfigurations'))]", + "input": { + "name": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].name]", + "properties": { + "primary": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].primary]", + "enableAcceleratedNetworking": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].enableAcceleratedNetworking]", + "ipConfigurations": [ + { + "name": "[concat(take(parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].name, sub(80, length('-defaultIpConfiguration'))), '-defaultIpConfiguration')]", + "properties": { + "subnet": { + "id": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].subnetId]" + }, + "primary": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].primary]", + "applicationGatewayBackendAddressPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].applicationGatewayBackendAddressPools]", + "loadBalancerBackendAddressPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].loadBalancerBackendAddressPools]", + "publicIPAddressConfiguration": "[if( equals( parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].pipName, ''), json('null'), union(json(concat('{\"name\": \"', parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].pipName, '\"}'))\n ,json('{\"properties\": { \"idleTimeoutInMinutes\": 15}}')))]" + } + } + ], + "networkSecurityGroup": "[if( equals( parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].nsgId, ''), json('null'),json(concat('{\"id\": \"', parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].nsgId, '\"}')))]" + } + } + } + ] + }, + "extensionProfile": { + "extensions": [ + { + "name": "GuestAttestation", + "properties": { + "publisher": "Microsoft.Azure.Security.LinuxAttestation", + "type": "GuestAttestation", + "typeHandlerVersion": "1.0", + "autoUpgradeMinorVersion": true, + "enableAutomaticUpgrade": true, + "settings": { + "AttestationConfig": { + "MaaSettings": { + "maaEndpoint": "", + "maaTenantName": "GuestAttestation" + }, + "AscSettings": { + "ascReportingEndpoint": "", + "ascReportingFrequency": "" + }, + "useCustomToken": "false", + "disableAlerts": "false" + } + } + } + } + ] + }, + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": true + } + }, + "osProfile": { + "computerNamePrefix": "[variables('namingInfix')]", + "adminUsername": "[parameters('adminUsername')]", + "linuxConfiguration": { + "disablePasswordAuthentication": true + } + }, + "securityProfile": { + "securityType": "[parameters('securityType')]", + "uefiSettings": { + "secureBootEnabled": "[parameters('secureBoot')]", + "vTpmEnabled": "[parameters('vTPM')]" + } + } + }, + "orchestrationMode": "Flexible", + "platformFaultDomainCount": "[parameters('platformFaultDomainCount')]" + }, + "sku": { + "name": "[parameters('instanceSize')]", + "capacity": "[int(parameters('instanceCount'))]" + } + } + ], + "outputs": { + "adminUsername": { + "type": "string", + "value": "[parameters('adminUsername')]" + } + } +} \ No newline at end of file diff --git a/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/pass-windows.json b/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/pass-windows.json new file mode 100644 index 00000000000..1956544eaba --- /dev/null +++ b/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/pass-windows.json @@ -0,0 +1,231 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string" + }, + "osDiskType": { + "type": "string" + }, + "addressPrefixes": { + "type": "array" + }, + "subnets": { + "type": "array" + }, + "virtualNetworkId": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, + "networkSecurityGroups": { + "type": "array" + }, + "networkInterfaceConfigurations": { + "type": "array" + }, + "vmName": { + "type": "string" + }, + "virtualMachineScaleSetName": { + "type": "string" + }, + "singlePlacementGroup": { + "type": "string" + }, + "instanceCount": { + "type": "string" + }, + "instanceSize": { + "type": "string" + }, + "scaleInPolicy": { + "type": "object" + }, + "overprovision": { + "type": "bool" + }, + "upgradePolicy": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "adminPassword": { + "type": "secureString" + }, + "securityType": { + "type": "string" + }, + "secureBoot": { + "type": "bool" + }, + "vTPM": { + "type": "bool" + }, + "platformFaultDomainCount": { + "type": "string" + } + }, + "variables": { + "storageApiVersion": "2021-01-01", + "virtualMachineScaleSetApiVersion": "2023-03-01", + "namingInfix": "[toLower(substring(concat(parameters('virtualMachineScaleSetName'), uniqueString(resourceGroup().id)), 0, 9))]" + }, + "resources": [ + { + "name": "[parameters('virtualNetworkName')]", + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2021-05-01", + "location": "[parameters('location')]", + "properties": { + "addressSpace": { + "addressPrefixes": "[parameters('addressPrefixes')]" + }, + "subnets": "[parameters('subnets')]" + } + }, + { + "name": "[parameters('networkSecurityGroups')[copyIndex()].name]", + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2019-02-01", + "location": "[parameters('location')]", + "properties": { + "securityRules": "[parameters('networkSecurityGroups')[copyIndex()].rules]" + }, + "copy": { + "name": "networkSecurityGroups", + "count": "[length(parameters('networkSecurityGroups'))]" + } + }, + { + "name": "pass-windows", + "type": "Microsoft.Compute/virtualMachineScaleSets", + "apiVersion": "[variables('virtualMachineScaleSetApiVersion')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]", + "networkSecurityGroups", + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]" + ], + "properties": { + "singlePlacementGroup": "[parameters('singlePlacementGroup')]", + "virtualMachineProfile": { + "storageProfile": { + "osDisk": { + "createOption": "fromImage", + "caching": "ReadWrite", + "managedDisk": { + "storageAccountType": "[parameters('osDiskType')]" + } + }, + "imageReference": { + "publisher": "MicrosoftWindowsServer", + "offer": "WindowsServer", + "sku": "2019-datacenter-gensecond", + "version": "latest" + } + }, + "networkProfile": { + "copy": [ + { + "name": "networkInterfaceConfigurations", + "count": "[length(parameters('networkInterfaceConfigurations'))]", + "input": { + "name": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].name]", + "properties": { + "primary": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].primary]", + "enableAcceleratedNetworking": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].enableAcceleratedNetworking]", + "ipConfigurations": [ + { + "name": "[concat(take(parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].name, sub(80, length('-defaultIpConfiguration'))), '-defaultIpConfiguration')]", + "properties": { + "subnet": { + "id": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].subnetId]" + }, + "primary": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].primary]", + "applicationGatewayBackendAddressPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].applicationGatewayBackendAddressPools]", + "loadBalancerBackendAddressPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].loadBalancerBackendAddressPools]", + "publicIPAddressConfiguration": "[if( equals( parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].pipName, ''), json('null'), union(json(concat('{\"name\": \"', parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].pipName, '\"}'))\n ,json('{\"properties\": { \"idleTimeoutInMinutes\": 15}}')))]", + "loadBalancerInboundNatPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].loadBalancerInboundNatPools]" + } + } + ], + "networkSecurityGroup": "[if( equals( parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].nsgId, ''), json('null'),json(concat('{\"id\": \"', parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].nsgId, '\"}')))]" + } + } + } + ] + }, + "extensionProfile": { + "extensions": [ + { + "name": "GuestAttestation", + "properties": { + "publisher": "Microsoft.Azure.Security.WindowsAttestation", + "type": "GuestAttestation", + "typeHandlerVersion": "1.0", + "autoUpgradeMinorVersion": true, + "enableAutomaticUpgrade": true, + "settings": { + "AttestationConfig": { + "MaaSettings": { + "maaEndpoint": "", + "maaTenantName": "GuestAttestation" + }, + "AscSettings": { + "ascReportingEndpoint": "", + "ascReportingFrequency": "" + }, + "useCustomToken": "false", + "disableAlerts": "false" + } + } + } + } + ] + }, + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": true + } + }, + "osProfile": { + "computerNamePrefix": "[variables('namingInfix')]", + "adminUsername": "[parameters('adminUsername')]", + "adminPassword": "[parameters('adminPassword')]", + "windowsConfiguration": { + "provisionVmAgent": true + } + }, + "securityProfile": { + "securityType": "[parameters('securityType')]", + "uefiSettings": { + "secureBootEnabled": "[parameters('secureBoot')]", + "vTpmEnabled": "[parameters('vTPM')]" + } + } + }, + "orchestrationMode": "Uniform", + "scaleInPolicy": "[parameters('scaleInPolicy')]", + "overprovision": "[parameters('overprovision')]", + "upgradePolicy": { + "mode": "[parameters('upgradePolicy')]" + }, + "platformFaultDomainCount": "[parameters('platformFaultDomainCount')]" + }, + "sku": { + "name": "[parameters('instanceSize')]", + "capacity": "[int(parameters('instanceCount'))]" + } + } + ], + "outputs": { + "adminUsername": { + "type": "string", + "value": "[parameters('adminUsername')]" + } + } +} \ No newline at end of file diff --git a/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/pass.json b/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/pass.json new file mode 100644 index 00000000000..9fa0bc825e2 --- /dev/null +++ b/tests/arm/checks/resource/example_VMScaleSetsAutoOSImagePatchingEnabled/pass.json @@ -0,0 +1,227 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string" + }, + "osDiskType": { + "type": "string" + }, + "addressPrefixes": { + "type": "array" + }, + "subnets": { + "type": "array" + }, + "virtualNetworkId": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, + "networkSecurityGroups": { + "type": "array" + }, + "networkInterfaceConfigurations": { + "type": "array" + }, + "vmName": { + "type": "string" + }, + "virtualMachineScaleSetName": { + "type": "string" + }, + "singlePlacementGroup": { + "type": "string" + }, + "instanceCount": { + "type": "string" + }, + "instanceSize": { + "type": "string" + }, + "scaleInPolicy": { + "type": "object" + }, + "overprovision": { + "type": "bool" + }, + "upgradePolicy": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "securityType": { + "type": "string" + }, + "secureBoot": { + "type": "bool" + }, + "vTPM": { + "type": "bool" + }, + "platformFaultDomainCount": { + "type": "string" + } + }, + "variables": { + "storageApiVersion": "2021-01-01", + "virtualMachineScaleSetApiVersion": "2023-03-01", + "namingInfix": "[toLower(substring(concat(parameters('virtualMachineScaleSetName'), uniqueString(resourceGroup().id)), 0, 9))]" + }, + "resources": [ + { + "name": "[parameters('virtualNetworkName')]", + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2021-05-01", + "location": "[parameters('location')]", + "properties": { + "addressSpace": { + "addressPrefixes": "[parameters('addressPrefixes')]" + }, + "subnets": "[parameters('subnets')]" + } + }, + { + "name": "[parameters('networkSecurityGroups')[copyIndex()].name]", + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2019-02-01", + "location": "[parameters('location')]", + "properties": { + "securityRules": "[parameters('networkSecurityGroups')[copyIndex()].rules]" + }, + "copy": { + "name": "networkSecurityGroups", + "count": "[length(parameters('networkSecurityGroups'))]" + } + }, + { + "name": "pass", + "type": "Microsoft.Compute/virtualMachineScaleSets", + "apiVersion": "[variables('virtualMachineScaleSetApiVersion')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]", + "networkSecurityGroups", + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]" + ], + "properties": { + "singlePlacementGroup": "[parameters('singlePlacementGroup')]", + "virtualMachineProfile": { + "storageProfile": { + "osDisk": { + "createOption": "fromImage", + "caching": "ReadWrite", + "managedDisk": { + "storageAccountType": "[parameters('osDiskType')]" + } + }, + "imageReference": { + "publisher": "canonical", + "offer": "0001-com-ubuntu-server-focal", + "sku": "20_04-lts-gen2", + "version": "latest" + } + }, + "networkProfile": { + "copy": [ + { + "name": "networkInterfaceConfigurations", + "count": "[length(parameters('networkInterfaceConfigurations'))]", + "input": { + "name": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].name]", + "properties": { + "primary": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].primary]", + "enableAcceleratedNetworking": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].enableAcceleratedNetworking]", + "ipConfigurations": [ + { + "name": "[concat(take(parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].name, sub(80, length('-defaultIpConfiguration'))), '-defaultIpConfiguration')]", + "properties": { + "subnet": { + "id": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].subnetId]" + }, + "primary": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].primary]", + "applicationGatewayBackendAddressPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].applicationGatewayBackendAddressPools]", + "loadBalancerBackendAddressPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].loadBalancerBackendAddressPools]", + "publicIPAddressConfiguration": "[if( equals( parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].pipName, ''), json('null'), union(json(concat('{\"name\": \"', parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].pipName, '\"}'))\n ,json('{\"properties\": { \"idleTimeoutInMinutes\": 15}}')))]", + "loadBalancerInboundNatPools": "[parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].loadBalancerInboundNatPools]" + } + } + ], + "networkSecurityGroup": "[if( equals( parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].nsgId, ''), json('null'),json(concat('{\"id\": \"', parameters('networkInterfaceConfigurations')[copyIndex('networkInterfaceConfigurations')].nsgId, '\"}')))]" + } + } + } + ] + }, + "extensionProfile": { + "extensions": [ + { + "name": "GuestAttestation", + "properties": { + "publisher": "Microsoft.Azure.Security.LinuxAttestation", + "type": "GuestAttestation", + "typeHandlerVersion": "1.0", + "autoUpgradeMinorVersion": true, + "enableAutomaticUpgrade": true, + "settings": { + "AttestationConfig": { + "MaaSettings": { + "maaEndpoint": "", + "maaTenantName": "GuestAttestation" + }, + "AscSettings": { + "ascReportingEndpoint": "", + "ascReportingFrequency": "" + }, + "useCustomToken": "false", + "disableAlerts": "false" + } + } + } + } + ] + }, + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": true + } + }, + "osProfile": { + "computerNamePrefix": "[variables('namingInfix')]", + "adminUsername": "[parameters('adminUsername')]", + "linuxConfiguration": { + "disablePasswordAuthentication": true + } + }, + "securityProfile": { + "securityType": "[parameters('securityType')]", + "uefiSettings": { + "secureBootEnabled": "[parameters('secureBoot')]", + "vTpmEnabled": "[parameters('vTPM')]" + } + } + }, + "orchestrationMode": "Uniform", + "scaleInPolicy": "[parameters('scaleInPolicy')]", + "overprovision": "[parameters('overprovision')]", + "upgradePolicy": { + "mode": "[parameters('upgradePolicy')]" + }, + "platformFaultDomainCount": "[parameters('platformFaultDomainCount')]" + }, + "sku": { + "name": "[parameters('instanceSize')]", + "capacity": "[int(parameters('instanceCount'))]" + } + } + ], + "outputs": { + "adminUsername": { + "type": "string", + "value": "[parameters('adminUsername')]" + } + } +} \ No newline at end of file diff --git a/tests/arm/checks/resource/test_VMScaleSetsAutoOSImagePatchingEnabled.py b/tests/arm/checks/resource/test_VMScaleSetsAutoOSImagePatchingEnabled.py new file mode 100644 index 00000000000..22f35bd50b7 --- /dev/null +++ b/tests/arm/checks/resource/test_VMScaleSetsAutoOSImagePatchingEnabled.py @@ -0,0 +1,44 @@ +import unittest +from pathlib import Path + +from checkov.arm.checks.resource.VMScaleSetsAutoOSImagePatchingEnabled import check +from checkov.arm.runner import Runner +from checkov.runner_filter import RunnerFilter + + +class TestVMScaleSetsAutoOSImagePatchingEnabled(unittest.TestCase): + def test_summary(self): + # given + test_files_dir = Path(__file__).parent / "example_VMScaleSetsAutoOSImagePatchingEnabled" + + # when + report = Runner().run(root_folder=str(test_files_dir), runner_filter=RunnerFilter(checks=[check.id])) + + # then + summary = report.get_summary() + + passing_resources = { + "Microsoft.Compute/virtualMachineScaleSets.pass", + "Microsoft.Compute/virtualMachineScaleSets.pass-windows", + } + failing_resources = { + "Microsoft.Compute/virtualMachineScaleSets.fail", + "Microsoft.Compute/virtualMachineScaleSets.fail2", + "Microsoft.Compute/virtualMachineScaleSets.fail-windows", + "Microsoft.Compute/virtualMachineScaleSets.fail-windows2", + } + + passed_check_resources = {c.resource for c in report.passed_checks} + failed_check_resources = {c.resource for c in report.failed_checks} + + self.assertEqual(summary["passed"], len(passing_resources)) + self.assertEqual(summary["failed"], len(failing_resources)) + self.assertEqual(summary["skipped"], 0) + self.assertEqual(summary["parsing_errors"], 0) + + self.assertEqual(passing_resources, passed_check_resources) + self.assertEqual(failing_resources, failed_check_resources) + + +if __name__ == "__main__": + unittest.main()