Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes Azure VM Standalone failing on data disks #3263 #3264

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/CHANGELOG-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers

## Unreleased

What's changed since v1.41.3:

- Bug fixes:
- Fixed Azure VM Standalone failing on data disks check by @BernieWhite.
[#3263](https://github.com/Azure/PSRule.Rules.Azure/issues/3263)

## v1.41.3

What's changed since v1.41.2:
Expand Down
137 changes: 69 additions & 68 deletions docs/en/rules/Azure.VM.Standalone.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
---
reviewed: 2022-07-09
reviewed: 2025-02-27
severity: Important
pillar: Reliability
category: RE:04 Target metrics
resource: Virtual Machine
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.VM.Standalone/
---

# Standalone Virtual Machine
# Virtual Machine is not configured for improved SLA

## SYNOPSIS

Use VM features to increase reliability and improve covered SLA for VM configurations.
Single instance VMs are a single point of failure, however reliability can be improved by using premium storage.

## DESCRIPTION

Expand All @@ -29,73 +29,15 @@ Taking advantage of some of the features of Azure can further increase the avail
Each Availability Zone has a distinct power source, network, and cooling.
- **Availability Sets** - is a logical grouping of VMs that allows Azure to understand how your application is built.
By understanding the distinct tiers of the application, Azure can better organize compute and storage to improve availability.
- **Solid State Storage (SSD) Disks** - high performance block-level storage with three replicas of your data.
- **Premium Solid State Storage (SSD) Disks** - high performance block-level storage with three replicas of your data.
When you use a mix of storage for OS and data disk attached to your VMs, the SLA is based on the lowest performing disk.

## RECOMMENDATION

Consider using availability zones/ sets or only premium/ ultra disks to improve SLA.

## EXAMPLES

### Configure with Azure template

To deploy VMs that pass this rule with on of the following:

- Deploy the VM in an Availability Set by specifying `properties.availabilitySet.id` in code.
- Deploy the VM in an Availability Zone by specifying `zones` with `1`, `2`, or `3` in code.
- Deploy the VM using only premium disks for OS and data disks by specifying `storageAccountType` as `Premium_LRS`.

For example:

```json
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2022-03-01",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"zones": [
"1"
],
"properties": {
"hardwareProfile": {
"vmSize": "Standard_D2s_v3"
},
"osProfile": {
"computerName": "[parameters('name')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]"
},
"storageProfile": {
"imageReference": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "[parameters('sku')]",
"version": "latest"
},
"osDisk": {
"name": "[format('{0}-disk0', parameters('name'))]",
"caching": "ReadWrite",
"createOption": "FromImage",
"managedDisk": {
"storageAccountType": "Premium_LRS"
}
}
},
"licenseType": "Windows_Server",
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', format('{0}-nic0', parameters('name')))]"
}
]
}
},
"dependsOn": [
"[resourceId('Microsoft.Network/networkInterfaces', format('{0}-nic0', parameters('name')))]"
]
}
```

### Configure with Bicep

To deploy VMs that pass this rule with on of the following:
Expand All @@ -107,7 +49,7 @@ To deploy VMs that pass this rule with on of the following:
For example:

```bicep
resource vm1 'Microsoft.Compute/virtualMachines@2022-03-01' = {
resource vm 'Microsoft.Compute/virtualMachines@2024-07-01' = {
name: name
location: location
zones: [
Expand Down Expand Up @@ -150,11 +92,70 @@ resource vm1 'Microsoft.Compute/virtualMachines@2022-03-01' = {
}
```

<!-- external:avm avm/res/compute/virtual-machine zone -->

### Configure with Azure template

To deploy VMs that pass this rule with on of the following:

- Deploy the VM in an Availability Set by specifying `properties.availabilitySet.id` in code.
- Deploy the VM in an Availability Zone by specifying `zones` with `1`, `2`, or `3` in code.
- Deploy the VM using only premium disks for OS and data disks by specifying `storageAccountType` as `Premium_LRS`.

For example:

```json
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2024-07-01",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"zones": [
"1"
],
"properties": {
"hardwareProfile": {
"vmSize": "Standard_D2s_v3"
},
"osProfile": {
"computerName": "[parameters('name')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]"
},
"storageProfile": {
"imageReference": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "[parameters('sku')]",
"version": "latest"
},
"osDisk": {
"name": "[format('{0}-disk0', parameters('name'))]",
"caching": "ReadWrite",
"createOption": "FromImage",
"managedDisk": {
"storageAccountType": "Premium_LRS"
}
}
},
"licenseType": "Windows_Server",
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]"
}
]
}
},
"dependsOn": [
"[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]"
]
}
```

## LINKS

- [RE:04 Target metrics](https://learn.microsoft.com/azure/well-architected/reliability/metrics)
- [Virtual Machine SLA](https://azure.microsoft.com/support/legal/sla/virtual-machines)
- [Availability options for virtual machines in Azure](https://learn.microsoft.com/azure/virtual-machines/availability)
- [Manage the availability of Windows virtual machines in Azure](https://learn.microsoft.com/azure/virtual-machines/windows/manage-availability)
- [Manage the availability of Linux virtual machines](https://learn.microsoft.com/azure/virtual-machines/linux/manage-availability)
- [Virtual Machine SLA](https://www.microsoft.com/licensing/docs/view/Service-Level-Agreements-SLA-for-Online-Services)
- [Availability options for Azure Virtual Machines](https://learn.microsoft.com/azure/virtual-machines/availability)
- [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.compute/virtualmachines)
4 changes: 2 additions & 2 deletions docs/examples/resources/vm.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ param subnetId string
param amaIdentityId string

// An example virtual machine running Windows Server and one data disk attached.
resource vm 'Microsoft.Compute/virtualMachines@2024-03-01' = {
resource vm 'Microsoft.Compute/virtualMachines@2024-07-01' = {
name: name
location: location
identity: {
Expand Down Expand Up @@ -146,7 +146,7 @@ resource config 'Microsoft.Maintenance/configurationAssignments@2023-04-01' = {
}

// An example virtual machine with Azure Hybrid Benefit.
resource vm_with_benefit 'Microsoft.Compute/virtualMachines@2023-09-01' = {
resource vm_with_benefit 'Microsoft.Compute/virtualMachines@2024-07-01' = {
name: name
location: location
zones: [
Expand Down
8 changes: 4 additions & 4 deletions docs/examples/resources/vm.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.32.4.45862",
"templateHash": "13775676563717028722"
"version": "0.33.93.31351",
"templateHash": "2836501364278978101"
}
},
"parameters": {
Expand Down Expand Up @@ -64,7 +64,7 @@
"resources": [
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2024-03-01",
"apiVersion": "2024-07-01",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"identity": {
Expand Down Expand Up @@ -193,7 +193,7 @@
},
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2023-09-01",
"apiVersion": "2024-07-01",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"zones": [
Expand Down
17 changes: 13 additions & 4 deletions src/PSRule.Rules.Azure/rules/Azure.VM.Rule.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ metadata:
name: Azure.VM.Standalone
ref: AZR-000239
tags:
release: 'GA'
ruleSet: '2020_06'
release: GA
ruleSet: 2020_06
Azure.WAF/pillar: Reliability
spec:
type:
Expand All @@ -31,8 +31,17 @@ spec:
hasValue: true
- allOf:
- field: properties.storageProfile.osDisk.managedDisk.storageAccountType
equals: Premium_LRS
- field: properties.storageProfile.dataDisks[[email protected] != 'Premium_LRS' && @.managedDisk.storageAccountType != 'Premium_ZRS' && @.managedDisk.storageAccountType != 'UltraSSD_LRS']
in:
- Premium_LRS
- Premium_ZRS
- field: properties.storageProfile.dataDisks
allOf:
- field: managedDisk.storageAccountType
notIn:
- Premium_LRS
- Premium_ZRS
- PremiumV2_LRS
- UltraSSD_LRS
count: 0

---
Expand Down
Loading
Loading