Running dev and test Compute Engine VMs with no off-hours schedule
What does ZopNight detect here?
Compute Engine stops billing vCPU and memory while a VM is `TERMINATED`, so dev and test VMs that run all night pay for hours nobody works. ZopNight flags running non-production VMs without a `schedule` label and prices a recurring stop and start schedule from the share of the week the suggested schedule removes.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-110 |
| Category | schedule |
| Severity | medium |
| Metric | none — pure configuration read |
| Threshold | dev/test VM running with no schedule |
| Source | ZopNight |
| Permissions used | compute.instances.list · compute.instances.get · compute.resourcePolicies.list · monitoring.timeSeries.list |
Where it applies
Office-hours VMs billed around the clock
A VM stopped overnight costs nothing for compute during those hours. Google’s
instance lifecycle page
lists CPU as billable only in RUNNING and PENDING_STOP. A development VM used from nine to
six, Monday to Friday, is busy for roughly a quarter of the week and billed for all of it.
Compute Engine has a native way to fix this: instance schedules, a resource policy that starts and stops attached VMs on cron expressions in a time zone you choose.
Spotting unscheduled dev and test VMs
gcloud compute instances list --filter="status=RUNNING" \ --format="table(name,zone,labels.list())"gcloud compute resource-policies listLook for names or labels that say dev, test, QA or staging, and check whether they appear in any instance schedule.
Evidence the VM is non-production
The VM must not be stopped and must look non-production: a name containing dev, test, qa,
staging, sandbox or demo, or a dev or test environment label. A VM already carrying a schedule
label is left alone. ZopNight then needs a measured off-hours pattern from the VM’s usage heatmap
and a suggested stop and start schedule built from it.
Guard rails before any schedule is proposed
Production signals win: a production-looking name or environment label ends the check. VMs whose
name carries a dr or standby token are excluded as disaster recovery capacity, since they
must be ready at any hour. Self-managed databases, caches and message brokers are excluded
too, because a quiet window does not prove durable state is safe to stop. A VM idle for 95% or
more of the week is not a scheduling case at all; it goes to
Idle GCP VM Instance.
Hours the schedule actually removes
saving = monthly VM cost x share of the week the suggested schedule keeps the VM stoppedZopNight prices only what the proposed schedule does, not the VM’s total idle time.
Putting the VM on an instance schedule
-
Review the proposed start, stop and time zone with the team that uses the VM.
-
Create a schedule, following Google’s scheduling guide:
Terminal window gcloud compute resource-policies create instance-schedule dev-hours --region=REGION \--vm-start-schedule='45 7 * * 1-5' --vm-stop-schedule='0 19 * * 1-5' --timezone=Europe/London -
Attach it:
gcloud compute instances add-resource-policies VM_NAME --zone=ZONE --resource-policies=dev-hours. -
Grant the Compute Engine Service Agent permission to start and stop instances, or the schedule fails.