Skip to content

Commit 11964e1

Browse files
feat(query): implements "Beta - VM Without Managed Disk" (#7856)
Co-authored-by: Artur Ribeiro <153724638+cx-artur-ribeiro@users.noreply.github.com>
1 parent 12a2ea9 commit 11964e1

12 files changed

Lines changed: 284 additions & 0 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"id": "0536c90c-714e-4184-991e-3fed8d8b7b46",
3+
"queryName": "Beta - VM Without Managed Disk",
4+
"severity": "MEDIUM",
5+
"category": "Resource Management",
6+
"descriptionText": "Virtual machine resources should set a managed disk for encryption, resilience and reduction of costs",
7+
"descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_virtual_machine",
8+
"platform": "Terraform",
9+
"descriptionID": "0536c90c",
10+
"cloudProvider": "azure",
11+
"cwe": "922",
12+
"riskScore": "3.0",
13+
"experimental": "true"
14+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package Cx
2+
3+
import data.generic.common as common_lib
4+
import data.generic.terraform as tf_lib
5+
6+
types := {"azurerm_virtual_machine", "azurerm_linux_virtual_machine", "azurerm_windows_virtual_machine", "azurerm_virtual_machine_scale_set"}
7+
8+
CxPolicy[result] {
9+
resource := input.document[i].resource[types[t]][name]
10+
11+
results := get_results(resource, name, types[t])
12+
13+
result := {
14+
"documentId": input.document[i].id,
15+
"resourceType": types[t],
16+
"resourceName": tf_lib.get_resource_name(resource, name),
17+
"searchKey": results.searchKey,
18+
"issueType": results.issueType,
19+
"keyExpectedValue": results.keyExpectedValue,
20+
"keyActualValue": results.keyActualValue,
21+
"searchLine": results.searchLine
22+
}
23+
}
24+
25+
get_results(resource, name, type) = results {
26+
type == "azurerm_virtual_machine"
27+
not common_lib.valid_key(resource, "storage_os_disk")
28+
results := {
29+
"searchKey": sprintf("azurerm_virtual_machine[%s]", [name]),
30+
"issueType": "MissingAttribute",
31+
"keyExpectedValue": sprintf("'azurerm_virtual_machine[%s].storage_os_disk' should be defined and not null", [name]),
32+
"keyActualValue": sprintf("'azurerm_virtual_machine[%s].storage_os_disk' is undefined or null", [name]),
33+
"searchLine": common_lib.build_search_line(["resource", "azurerm_virtual_machine", name], [])
34+
}
35+
} else = results {
36+
type == "azurerm_virtual_machine"
37+
common_lib.valid_key(resource.storage_os_disk, "vhd_uri")
38+
results := {
39+
"searchKey": sprintf("azurerm_virtual_machine[%s].storage_os_disk.vhd_uri", [name]),
40+
"issueType": "IncorrectValue",
41+
"keyExpectedValue": sprintf("'azurerm_virtual_machine[%s].storage_os_disk.vhd_uri' should not be set", [name]),
42+
"keyActualValue": sprintf("'azurerm_virtual_machine[%s].storage_os_disk.vhd_uri' is set", [name]),
43+
"searchLine": common_lib.build_search_line(["resource", "azurerm_virtual_machine", name, "storage_os_disk", "vhd_uri"], [])
44+
}
45+
} else = results {
46+
type == "azurerm_virtual_machine"
47+
not common_lib.valid_key(resource.storage_os_disk, "managed_disk_id")
48+
not common_lib.valid_key(resource.storage_os_disk, "managed_disk_type")
49+
results := {
50+
"searchKey": sprintf("azurerm_virtual_machine[%s].storage_os_disk", [name]),
51+
"issueType": "MissingAttribute",
52+
"keyExpectedValue": sprintf("'azurerm_virtual_machine[%s].storage_os_disk' should define a 'managed_disk_id' or 'managed_disk_type'", [name]),
53+
"keyActualValue": sprintf("'azurerm_virtual_machine[%s].storage_os_disk' does not define or sets to null 'managed_disk_id' and 'managed_disk_type'", [name]),
54+
"searchLine": common_lib.build_search_line(["resource", "azurerm_virtual_machine", name, "storage_os_disk"], [])
55+
}
56+
} else = results {
57+
type == ["azurerm_linux_virtual_machine", "azurerm_windows_virtual_machine"][_]
58+
not common_lib.valid_key(resource, "os_managed_disk_id")
59+
results := {
60+
"searchKey": sprintf("%s[%s]", [type, name]),
61+
"issueType": "MissingAttribute",
62+
"keyExpectedValue": sprintf("'%s[%s].os_managed_disk_id' should be defined and not null", [type, name]),
63+
"keyActualValue": sprintf("'%s[%s].os_managed_disk_id' is undefined or null", [type, name]),
64+
"searchLine": common_lib.build_search_line(["resource", type, name], [])
65+
}
66+
} else = results {
67+
type == "azurerm_virtual_machine_scale_set"
68+
not common_lib.valid_key(resource.storage_profile_os_disk, "managed_disk_type")
69+
results := {
70+
"searchKey": sprintf("%s[%s]", [type, name]),
71+
"issueType": "MissingAttribute",
72+
"keyExpectedValue": sprintf("'%s[%s].storage_profile_os_disk.managed_disk_type' should be defined and not null", [type, name]),
73+
"keyActualValue": sprintf("'%s[%s].storage_profile_os_disk.managed_disk_type' is undefined or null", [type, name]),
74+
"searchLine": common_lib.build_search_line(["resource", type, name], [])
75+
}
76+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
resource "azurerm_virtual_machine" "negative1_1" {
2+
name = "${var.prefix}-vm"
3+
location = azurerm_resource_group.negative1_1.location
4+
resource_group_name = azurerm_resource_group.negative1_1.name
5+
network_interface_ids = [azurerm_network_interface.main.id]
6+
vm_size = "Standard_DS1_v2"
7+
8+
storage_os_disk {
9+
name = "myosdisk1"
10+
caching = "ReadWrite"
11+
create_option = "FromImage"
12+
managed_disk_type = "Standard_LRS"
13+
}
14+
}
15+
16+
resource "azurerm_virtual_machine" "negative1_2" {
17+
name = "${var.prefix}-vm"
18+
location = azurerm_resource_group.negative1_2.location
19+
resource_group_name = azurerm_resource_group.negative1_2.name
20+
network_interface_ids = [azurerm_network_interface.negative1_2.id]
21+
vm_size = "Standard_DS1_v2"
22+
23+
storage_os_disk {
24+
name = "myosdisk1"
25+
caching = "ReadWrite"
26+
create_option = "Attach"
27+
managed_disk_id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Compute/disks/myManagedDisk"
28+
}
29+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
resource "azurerm_linux_virtual_machine" "negative2" {
2+
name = "negative2-machine"
3+
resource_group_name = azurerm_resource_group.negative2.name
4+
location = azurerm_resource_group.negative2.location
5+
size = "Standard_F2"
6+
admin_username = "adminuser"
7+
8+
os_managed_disk_id = azurerm_managed_disk.negative2.id
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
resource "azurerm_windows_virtual_machine" "negative3" {
2+
name = "negative3-machine"
3+
resource_group_name = azurerm_resource_group.negative3.name
4+
location = azurerm_resource_group.negative3.location
5+
size = "Standard_F2"
6+
admin_username = "adminuser"
7+
8+
os_managed_disk_id = azurerm_managed_disk.negative3.id
9+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
resource "azurerm_virtual_machine_scale_set" "negative4" {
2+
name = "vmss-ssd-negative4"
3+
location = azurerm_resource_group.negative4.location
4+
resource_group_name = azurerm_resource_group.negative4.name
5+
upgrade_policy_mode = "Manual"
6+
7+
storage_profile_os_disk {
8+
caching = "ReadWrite"
9+
create_option = "FromImage"
10+
managed_disk_type = "StandardSSD_LRS"
11+
}
12+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
resource "azurerm_virtual_machine" "positive1" {
2+
name = "${var.prefix}-vm"
3+
location = azurerm_resource_group.positive1.location
4+
resource_group_name = azurerm_resource_group.positive1.name
5+
network_interface_ids = [azurerm_network_interface.main.id]
6+
vm_size = "Standard_DS1_v2"
7+
8+
# missing "storage_os_disk" (tecnically required)
9+
}
10+
11+
resource "azurerm_virtual_machine" "positive1_2" {
12+
name = "${var.prefix}-vm"
13+
location = azurerm_resource_group.positive1_2.location
14+
resource_group_name = azurerm_resource_group.positive1_2.name
15+
network_interface_ids = [azurerm_network_interface.main.id]
16+
vm_size = "Standard_DS1_v2"
17+
18+
storage_os_disk {
19+
name = "myosdisk1"
20+
create_option = "FromImage"
21+
vhd_uri = "https://<storageaccount>.blob.core.windows.net/<container>/<diskname>.vhd"
22+
# unmanaged disk
23+
}
24+
}
25+
26+
resource "azurerm_virtual_machine" "positive1_3" {
27+
name = "${var.prefix}-vm"
28+
location = azurerm_resource_group.positive1_3.location
29+
resource_group_name = azurerm_resource_group.positive1_3.name
30+
network_interface_ids = [azurerm_network_interface.main.id]
31+
vm_size = "Standard_DS1_v2"
32+
33+
34+
storage_os_disk {
35+
name = "myosdisk1"
36+
create_option = "FromImage"
37+
# missing managed_disk_type/managed_disk_id
38+
}
39+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
resource "azurerm_linux_virtual_machine" "positive2" {
2+
name = "positive2-machine"
3+
resource_group_name = azurerm_resource_group.positive2.name
4+
location = azurerm_resource_group.positive2.location
5+
size = "Standard_F2"
6+
admin_username = "adminuser"
7+
8+
# missing os_managed_disk_id
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
resource "azurerm_windows_virtual_machine" "positive3" {
2+
name = "positive3-machine"
3+
resource_group_name = azurerm_resource_group.positive3.name
4+
location = azurerm_resource_group.positive3.location
5+
size = "Standard_F2"
6+
admin_username = "adminuser"
7+
8+
# missing os_managed_disk_id
9+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
resource "azurerm_virtual_machine_scale_set" "positive4_1" {
2+
name = "vmss-premium-positive4_1"
3+
location = azurerm_resource_group.positive4_1.location
4+
resource_group_name = azurerm_resource_group.positive4_1.name
5+
upgrade_policy_mode = "Manual"
6+
7+
storage_profile_os_disk {
8+
caching = "ReadOnly"
9+
create_option = "FromImage"
10+
vhd_containers = [
11+
"https://mystorageaccount.blob.core.windows.net/vhds/"
12+
]
13+
# vhd_containers instead of "managed_disk_type"
14+
}
15+
}
16+
17+
resource "azurerm_virtual_machine_scale_set" "positive4_2" {
18+
name = "vmss-premium-positive4_2"
19+
location = azurerm_resource_group.positive4_2.location
20+
resource_group_name = azurerm_resource_group.positive4_2.name
21+
upgrade_policy_mode = "Manual"
22+
23+
storage_profile_os_disk {
24+
caching = "ReadOnly"
25+
create_option = "FromImage"
26+
os_type = "Linux" # Required when using "image"
27+
image = "https://mystorageaccount.blob.core.windows.net/system/Microsoft.Compute/Images/custom-os-image/osDisk.vhd"
28+
# image instead of "managed_disk_type"
29+
}
30+
}

0 commit comments

Comments
 (0)