Skip to content

Commit b2abdbe

Browse files
feat(gcp-compute): add check to ensure VMs are not preemptible or spot (#9342)
Co-authored-by: HugoPBrito <[email protected]>
1 parent dc852b4 commit b2abdbe

File tree

6 files changed

+467
-3
lines changed

6 files changed

+467
-3
lines changed

prowler/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
77
### Added
88
- `cloudstorage_uses_vpc_service_controls` check for GCP provider [(#9256)](https://github.com/prowler-cloud/prowler/pull/9256)
99
- `repository_immutable_releases_enabled` check for GitHub provider [(#9162)](https://github.com/prowler-cloud/prowler/pull/9162)
10+
- `compute_instance_preemptible_vm_disabled` check for GCP provider [(#9342)](https://github.com/prowler-cloud/prowler/pull/9342)
1011
- `compute_instance_automatic_restart_enabled` check for GCP provider [(#9271)](https://github.com/prowler-cloud/prowler/pull/9271)
1112

1213
---

prowler/providers/gcp/services/compute/compute_instance_preemptible_vm_disabled/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"Provider": "gcp",
3+
"CheckID": "compute_instance_preemptible_vm_disabled",
4+
"CheckTitle": "VM instance is not configured as preemptible or Spot VM",
5+
"CheckType": [],
6+
"ServiceName": "compute",
7+
"SubServiceName": "",
8+
"ResourceIdTemplate": "",
9+
"Severity": "medium",
10+
"ResourceType": "compute.googleapis.com/Instance",
11+
"Description": "This check verifies that VM instances are not configured as **preemptible** or **Spot VMs**.\n\nBoth preemptible and Spot VMs can be terminated by Google at any time when resources are needed elsewhere, making them unsuitable for production and business-critical workloads. Spot VMs are the newer version of preemptible VMs and are Google's recommended approach for interruptible workloads.",
12+
"Risk": "Preemptible and Spot VMs may be **terminated at any time** by Google Cloud, causing:\n\n- **Service disruptions** for production workloads\n- **Data loss** if workloads are not fault-tolerant\n- **Availability issues** for business-critical applications\n\nThey are designed for batch jobs and fault-tolerant workloads only.",
13+
"RelatedUrl": "",
14+
"AdditionalURLs": [
15+
"https://cloud.google.com/compute/docs/instances/preemptible",
16+
"https://cloud.google.com/compute/docs/instances/spot",
17+
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/ComputeEngine/disable-preemptibility.html"
18+
],
19+
"Remediation": {
20+
"Code": {
21+
"CLI": "",
22+
"NativeIaC": "",
23+
"Other": "1. Go to Compute Engine console\n2. Select the preemptible or Spot VM instance\n3. Create a machine image from the instance\n4. Create a new instance from the machine image\n5. During creation, set **VM provisioning model** to **Standard** (not Spot)\n6. Delete the original preemptible or Spot VM instance",
24+
"Terraform": "```hcl\nresource \"google_compute_instance\" \"example_resource\" {\n name = \"example-instance\"\n machine_type = \"e2-medium\"\n zone = \"us-central1-a\"\n\n scheduling {\n # Use standard provisioning model for production workloads (not Spot)\n provisioning_model = \"STANDARD\"\n # Also ensure preemptible is false (legacy field)\n preemptible = false\n }\n}\n```"
25+
},
26+
"Recommendation": {
27+
"Text": "Use standard provisioning model for production and business-critical VM instances. Preemptible and Spot VMs should only be used for fault-tolerant, batch processing, or non-critical workloads that can handle interruptions.",
28+
"Url": "https://hub.prowler.com/checks/compute_instance_preemptible_vm_disabled"
29+
}
30+
},
31+
"Categories": [
32+
"resilience"
33+
],
34+
"DependsOn": [],
35+
"RelatedTo": [],
36+
"Notes": ""
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from prowler.lib.check.models import Check, Check_Report_GCP
2+
from prowler.providers.gcp.services.compute.compute_client import compute_client
3+
4+
5+
class compute_instance_preemptible_vm_disabled(Check):
6+
"""
7+
Ensure GCP Compute Engine VM instances are not preemptible or Spot VMs.
8+
9+
- PASS: VM instance is not preemptible (preemptible=False) and not Spot
10+
(provisioningModel != "SPOT").
11+
- FAIL: VM instance is preemptible (preemptible=True) or Spot
12+
(provisioningModel="SPOT").
13+
"""
14+
15+
def execute(self) -> list[Check_Report_GCP]:
16+
findings = []
17+
for instance in compute_client.instances:
18+
report = Check_Report_GCP(metadata=self.metadata(), resource=instance)
19+
report.status = "PASS"
20+
report.status_extended = (
21+
f"VM Instance {instance.name} is not preemptible or Spot VM."
22+
)
23+
24+
if instance.preemptible or instance.provisioning_model == "SPOT":
25+
report.status = "FAIL"
26+
vm_type = "preemptible" if instance.preemptible else "Spot VM"
27+
report.status_extended = (
28+
f"VM Instance {instance.name} is configured as {vm_type}."
29+
)
30+
31+
findings.append(report)
32+
return findings

prowler/providers/gcp/services/compute/compute_service.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,13 @@ def _get_instances(self, zone):
136136
automatic_restart=instance.get("scheduling", {}).get(
137137
"automaticRestart", False
138138
),
139-
preemptible=instance.get("scheduling", {}).get(
140-
"preemptible", False
141-
),
142139
provisioning_model=instance.get("scheduling", {}).get(
143140
"provisioningModel", "STANDARD"
144141
),
145142
project_id=project_id,
143+
preemptible=instance.get("scheduling", {}).get(
144+
"preemptible", False
145+
),
146146
)
147147
)
148148

0 commit comments

Comments
 (0)