Suspend and resume a VM

Stay organized with collections Save and categorize content based on your preferences.

This document describes how to suspend and resume a virtual machine (VM) instance. For information about how to stop and start an instance, see Stopping and starting an instance. For information about the instance lifecycle, see Instance Life Cycle documentation.

If you want to keep your VM instance around but do not want to be charged for it when it is not in use, you can suspend the VM. When you suspend a VM, Google preserves the VM in your project and moves the contents of the VM's memory to storage. While the VM is suspended, Google only charges for the storage used to preserve the VM's memory. Attributes like static IP addresses remain in place so that network functions work as expected when you resume the VM. After resuming, Google moves the VM's memory from storage back to the instance, and starts charging you for the now-running VM instance.

Suspending an instance is ideal for:

  • Development and test environments that are not being fully utilized during off periods, such as during evenings or weekends, for cost savings or faster initialization than creating new VM instances.
  • Applications that require a long period of initialization after the instance has finished booting, but before the application is ready to service its first request, such as virtual developer workstations or complex Java applications.

How suspension works

Suspending an instance sends an ACPI S3 suspend signal to the instance's operating system. Suspending an instance is analogous to closing the lid of your laptop, putting the instance into a SUSPENDED state.

Suspending an instance differs from stopping an instance in the following ways:

With the exception of local SSD data, all resources that are attached to the instance remain attached to the instance and will be charged, including persistent disks and static or reserved external IP addresses. All of these resources are charged according to the price sheet, even if an instance is suspended.

You cannot suspend an instance by using the standard processes that are built into the guest environment. Commands, such as the systemctl suspend command in Ubuntu 16.04 and later, are not available. You can only use the Google Cloud CLI or the Compute Engine API to suspend an instance.

If you don't care about restoring an instance's memory and device state when you resume the instance later, you can stop the instance instead, which does not incur additional storage charges.

Before you begin

Limitations

The following limitations apply for this feature:

  • You cannot suspend an instance that uses a GPU.
  • You can suspend an instance that has attached local SSD, but the local SSD contents must be discarded using a special flag for discarding local SSD data.
  • You cannot suspend an instance by using the standard processes that are built into the guest environment. Commands, such as the systemctl suspend command in Ubuntu 16.04 and later, are not available. The in-guest signal is ignored.
  • You can only suspend an instance for up to 60 days before the VM is automatically stopped.
  • You cannot suspend instances with more than 120 GB of memory.
  • You can suspend preemptible instances, but the preemptible instance might be terminated before it is successfully suspended.
  • You cannot suspend an E2 instance.
  • You cannot suspend a Confidential VM.
  • You cannot suspend a VM that has CSEK-protected disks attached.

Local SSDs and preemptible VMs

Local SSD content is not preserved when an instance is suspended. By default, suspending an instance that has a local SSD returns an error. You can override this default behavior by specifying a flag to discard local SSD data, which lets the instance be suspended and resumed, but discards the contents of the local SSD in the process. In this scenario, Compute Engine resumes the instance with the same number of local SSD volumes attached, but the volumes will be empty and uninitialized.

You can suspend a preemptible VM but if preemption (not the advance warning that precedes the preemption) occurs before the suspend operation completes, the suspend exits and the instance is preempted.

OS compatibility

Most operating systems (OSes) offered on Compute Engine support the suspend and resume functionality, but there are a few OSes that do not. Review the OS details page for the full list.

Pricing

When you suspend an instance, you are charged for:

  • Instance memory (see Suspended VM instances).
  • Any persistent disk usage for the boot disk and any additional disks attached to the instance (see Persistent disk pricing).
  • Any static IPs attached to the instance.
  • Suspending VMs might save on your software licensing fees. For example, if you suspend Windows VMs, you do not incur Windows license fees. License fees for other images might have different terms and conditions and may result in charges even when suspended.

Suspend an instance

To suspend an instance, use the Google Cloud console , the gcloud CLI, the API, or the Cloud Client Libraries.

You cannot suspend an instance by using the standard processes that are built into the guest environment. You can use the Google Cloud console , the Google Cloud CLI, or the API to suspend an instance.

Suspend operation can fail if it's triggered too soon after the instance was started. The instance needs to be fully started (including processes like Guest Agent) for the suspend operation to succeed.

Console

  1. In the Google Cloud console, go to the VM instances page.

    Go to the VM instances page

  2. Select one or more instances to suspend.

  3. Click Suspend.

  4. When prompted, if you want to discard local SSD data, select Discard the SSD content. When your instance is resumed, any local SSD data on the instance will have been discarded.

gcloud

To suspend an instance in the Google Cloud CLI:

 gcloud compute instances suspend VM_NAME

After you make a request to suspend an instance, it can take some time for Compute Engine to preserve all the data necessary for the instance. During this time, you continue to be charged for the instance while it remains running.

A suspended instance is marked by SUSPENDED status. Check an instance's status by making a describe request:

gcloud compute instances describe VM_NAME

To suspend an instance with local SSD data, you must discard the local SSD data by providing the beta --discard-local-ssd flag:

gcloud beta compute instances suspend VM_NAME --discard-local-ssd

API

In the API, make a request using the instances.suspend method:

https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/suspend

Replace the following:

  • PROJECT_ID: the project ID
  • ZONE: the zone of the VM
  • VM_NAME: the instance that you want to suspend

After you make a request to suspend an instance, it can take some time for Compute Engine to preserve all the data necessary for the instance. During this time, you are charged for the instance while it remains running.

Compute Engine marks suspended instance with the SUSPENDED status. Check an instance's status by making a GET request:

GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME

The instance's status is visible in the status field. For example:

...
"zone": "https://content.googleapis.com/compute/v1/projects/example-project/zones/us-central1-a",
"status": "SUSPENDED",
"name": "example-vm",
...

To suspend an instance with local SSD data, you must discard the local SSD data by providing the discardLocalSsd query parameter, which is currently in beta:

https://www.googleapis.com/compute/beta/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/suspend?discardLocalSsd=true

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
)

// suspendInstance suspends a running Google Compute Engine instance.
func suspendInstance(w io.Writer, projectID, zone, instanceName string) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"

	ctx := context.Background()
	instancesClient, err := compute.NewInstancesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewInstancesRESTClient: %v", err)
	}
	defer instancesClient.Close()

	req := &computepb.SuspendInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
	}

	op, err := instancesClient.Suspend(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to suspend instance: %v", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %v", err)
	}

	fmt.Fprintf(w, "Instance suspended\n")

	return nil
}

Java


import com.google.cloud.compute.v1.Instance.Status;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class SuspendInstance {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // project: project ID or project number of the Cloud project your instance belongs to.
    // zone: name of the zone your instance belongs to.
    // instanceName: name of the instance your want to suspend.

    String project = "your-project-id";
    String zone = "zone-name";
    String instanceName = "instance-name";

    suspendInstance(project, zone, instanceName);
  }

  // Suspend a running Google Compute Engine instance.
  // For limitations and compatibility on which instances can be suspended,
  // see: https://cloud.google.com/compute/docs/instances/suspend-resume-instance#limitations
  public static void suspendInstance(String project, String zone, String instanceName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Instantiates a client.
    try (InstancesClient instancesClient = InstancesClient.create()) {

      Operation operation = instancesClient.suspendAsync(project, zone, instanceName)
          .get(300, TimeUnit.SECONDS);

      if (operation.hasError() || !instancesClient.get(project, zone, instanceName).getStatus()
          .equalsIgnoreCase(Status.SUSPENDED.toString())) {
        System.out.println("Cannot suspend instance. Try again!");
        return;
      }

      System.out.printf("Instance suspended successfully ! %s", instanceName);
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const zone = 'europe-central2-b';
// const instanceName = 'YOUR_INSTANCE_NAME';

const compute = require('@google-cloud/compute');

// Suspends a running Google Compute Engine instance.
async function suspendInstance() {
  const instancesClient = new compute.InstancesClient();

  const [response] = await instancesClient.suspend({
    project: projectId,
    zone,
    instance: instanceName,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
      zone: operation.zone.split('/').pop(),
    });
  }

  console.log('Instance suspended.');
}

suspendInstance();

PHP

use Google\Cloud\Compute\V1\InstancesClient;

/**
 * Suspend a running Google Compute Engine instance.
 *
 * @param string $projectId Project ID or project number of the Cloud project your instance belongs to.
 * @param string $zone Name of the zone your instance belongs to.
 * @param string $instanceName Name of the instance you want to suspend.
  *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function suspend_instance(
    string $projectId,
    string $zone,
    string $instanceName
) {
    // Suspend the running Compute Engine instance using InstancesClient.
    $instancesClient = new InstancesClient();
    $operation = $instancesClient->suspend($instanceName, $projectId, $zone);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Instance %s suspended successfully' . PHP_EOL, $instanceName);
    } else {
        $error = $operation->getError();
        printf('Failed to suspend instance: %s' . PHP_EOL, $error->getMessage());
    }
}

Python

import sys
import time
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    This method will wait for the extended (long-running) operation to
    complete. If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def suspend_instance(project_id: str, zone: str, instance_name: str) -> None:
    """
    Suspend a running Google Compute Engine instance.
    Args:
        project_id: project ID or project number of the Cloud project your instance belongs to.
        zone: name of the zone your instance belongs to.
        instance_name: name of the instance you want to suspend.
    """
    instance_client = compute_v1.InstancesClient()

    operation = instance_client.suspend(
        project=project_id, zone=zone, instance=instance_name
    )

    wait_for_extended_operation(operation, "suspend instance")
    return

Resume a suspended instance

You can only resume an instance if there is sufficient capacity in the zone where the VM resides. In the majority of cases, this is not an issue but if you do experience capacity issues, retry your resume request again at a later time.

To resume a suspended instance, use the Google Cloud console , the gcloud CLI, the API, or the Cloud Client Libraries.

Console

  1. In the Google Cloud console, go to the VM instances page.

    Go to the VM instances page

  2. Select one or more instances to resume.

  3. Click Start/Resume.

gcloud

To resume an instance in the Google Cloud CLI:

 gcloud compute instances resume VM_NAME

After you make a request to resume an instance, it can take some time for Compute Engine to restore all the data necessary for the instance. During this time, you are charged for the instance while it is resuming.

An instance is resumed when it is marked as RUNNING. Check an instance's status by making a describe request:

gcloud compute instances describe VM_NAME

API

Make a request to the instances.resume method:

https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/resume

Replace the following:

  • PROJECT_ID: the project ID for this request
  • ZONE: the zone of the VM
  • VM_NAME: the instance to resume

After you make a request to resume an instance, it can take some time for Compute Engine to restore all the data necessary for the instance. During this time, you are charged for the instance while it is resuming

Compute Engine marks the instance with the RUNNING status once the resume is complete. Check an instance's status by making a GET request:

GET https://compute.googleapis.com/compute/v1/projects/example-project/zones/us-central1-a/instances/example-instance

The instance's status is visible in the status field. For example:

...
"zone": "https://content.googleapis.com/compute/v1/projects/example-project/zones/us-central1-a",
"status": "RUNNING",
"name": "example-instance",
...

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
)

// resumeInstance resumes a suspended Google Compute Engine instance
// (with unencrypted disks).
func resumeInstance(w io.Writer, projectID, zone, instanceName string) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"

	ctx := context.Background()
	instancesClient, err := compute.NewInstancesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewInstancesRESTClient: %v", err)
	}
	defer instancesClient.Close()

	getInstanceReq := &computepb.GetInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
	}

	instance, err := instancesClient.Get(ctx, getInstanceReq)
	if err != nil {
		return fmt.Errorf("unable to get instance: %v", err)
	}

	if instance.GetStatus() != "SUSPENDED" {
		return fmt.Errorf(
			"only suspended instances can be resumed, instance %s is in %s state",
			instanceName,
			instance.GetStatus(),
		)
	}

	resumeInstanceReq := &computepb.ResumeInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
	}

	op, err := instancesClient.Resume(ctx, resumeInstanceReq)
	if err != nil {
		return fmt.Errorf("unable to resume instance: %v", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %v", err)
	}

	fmt.Fprintf(w, "Instance resumed\n")

	return nil
}

Java


import com.google.cloud.compute.v1.Instance.Status;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ResumeInstance {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // project: project ID or project number of the Cloud project your instance belongs to.
    // zone: name of the zone your instance belongs to.
    // instanceName: name of the instance your want to resume.

    String project = "your-project-id";
    String zone = "zone-name";
    String instanceName = "instance-name";

    resumeInstance(project, zone, instanceName);
  }

  // Resume a suspended Google Compute Engine instance (with unencrypted disks).
  // Instance state changes to RUNNING, if successfully resumed.
  public static void resumeInstance(String project, String zone, String instanceName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Instantiates a client.
    try (InstancesClient instancesClient = InstancesClient.create()) {

      String currentInstanceState = instancesClient.get(project, zone, instanceName).getStatus();

      // Check if the instance is currently suspended.
      if (!currentInstanceState.equalsIgnoreCase(Status.SUSPENDED.toString())) {
        throw new RuntimeException(
            String.format("Only suspended instances can be resumed. Instance %s is in %s state.",
                instanceName, currentInstanceState));
      }

      Operation operation = instancesClient.resumeAsync(project, zone, instanceName)
          .get(300, TimeUnit.SECONDS);

      if (operation.hasError() || !instancesClient.get(project, zone, instanceName).getStatus()
          .equalsIgnoreCase(
              Status.RUNNING.toString())) {
        System.out.println("Cannot resume instance. Try again!");
        return;
      }

      System.out.printf("Instance resumed successfully ! %s", instanceName);
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const zone = 'europe-central2-b';
// const instanceName = 'YOUR_INSTANCE_NAME';

const compute = require('@google-cloud/compute');

// Resumes a suspended Google Compute Engine instance (with unencrypted disks).
async function resumeInstance() {
  const instancesClient = new compute.InstancesClient();

  const [instance] = await instancesClient.get({
    project: projectId,
    zone,
    instance: instanceName,
  });

  if (instance.status !== 'SUSPENDED') {
    throw new Error(
      'Only suspended instances can be resumed.' +
        `Instance ${instanceName} is in ${instance.status} state.`
    );
  }

  const [response] = await instancesClient.resume({
    project: projectId,
    zone,
    instance: instanceName,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
      zone: operation.zone.split('/').pop(),
    });
  }

  console.log('Instance resumed.');
}

resumeInstance();

PHP

use Google\Cloud\Compute\V1\InstancesClient;

/**
 * Resume a suspended Google Compute Engine instance (with unencrypted disks).
 *
 * @param string $projectId Project ID or project number of the Cloud project your instance belongs to.
 * @param string $zone Name of the zone your instance belongs to.
 * @param string $instanceName Name of the instance you want to resume.
  *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function resume_instance(
    string $projectId,
    string $zone,
    string $instanceName
) {
    // Resume the suspended Compute Engine instance using InstancesClient.
    $instancesClient = new InstancesClient();
    $operation = $instancesClient->resume($instanceName, $projectId, $zone);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Instance %s resumed successfully' . PHP_EOL, $instanceName);
    } else {
        $error = $operation->getError();
        printf('Failed to resume instance: %s' . PHP_EOL, $error->getMessage());
    }
}

Python

import sys
import time
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    This method will wait for the extended (long-running) operation to
    complete. If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def resume_instance(project_id: str, zone: str, instance_name: str) -> None:
    """
    Resume a suspended Google Compute Engine instance (with unencrypted disks).
    Args:
        project_id: project ID or project number of the Cloud project your instance belongs to.
        zone: name of the zone your instance belongs to.
        instance_name: name of the instance you want to resume.
    """
    instance_client = compute_v1.InstancesClient()

    instance = instance_client.get(
        project=project_id, zone=zone, instance=instance_name
    )
    if instance.status != compute_v1.Instance.Status.SUSPENDED.name:
        raise RuntimeError(
            f"Only suspended instances can be resumed. "
            f"Instance {instance_name} is in {instance.status} state."
        )

    operation = instance_client.resume(
        project=project_id, zone=zone, instance=instance_name
    )

    wait_for_extended_operation(operation, "instance resumption")
    return

Suspend process

When you make a suspend request, you send an ACPI suspend signal to the VM instance. If the VM does not respond to the ACPI S3 suspend signal within a couple of minutes, Compute Engine cancels the suspend attempt and returns the VM to a RUNNING state.

The following table describes the effect of suspending a VM instance on its associated resources:

Resource Support
Memory Only VMs with less than or equal to 120 GB of memory can be suspended
Local SSD Local SSD data is discarded
Persistent disk Persistent HDD and SSD disks are retained
IP addresses Ephemeral IPs are released during suspension, but static IPs remain attached to the VM instances. If you would like to retain your ephemeral IP, promote it.
VM configuration (such as machine type, metadata, labels, etc.) All VM configurations, other than ephemeral IP addresses, are preserved and restored when the instance resumes.

Configuring a Debian VM to support suspend and resume

VMs running Debian 8 and 9 can suspend and resume, but they must be configured beforehand. To configure your Debian instance, complete one of the following sets of instructions, option A or option B. We recommend configuring the ACPID if possible (option A).

Option A

This option configures the ACPID to handle the sleep button event and adds a shell script for handling the sleep event.

  1. Connect to your VM instance using ssh:

    gcloud compute ssh VM_NAME
    
  2. On the VM instance, create a directory under the acpi folder:

    sudo mkdir -p /etc/acpi/events/
    
  3. Configure ACPID to handle the sleep button event:

    cat <<EOF | sudo tee /etc/acpi/events/sleepbtn-acpi-support
    event=button[ /]sleep
    action=/etc/acpi/sleepbtn-acpi-support.sh
    EOF
    
  4. Create the sleep event handling script:

    cat <<EOF | sudo tee /etc/acpi/sleepbtn-acpi-support.sh
    #!/bin/sh
    echo mem > /sys/power/state
    EOF
    
  5. Set up the permissions for the script:

    sudo chmod 755 /etc/acpi/sleepbtn-acpi-support.sh
    
  6. Restart ACPID:

    sudo systemctl restart acpid.service
    

Option B

  1. Connect to your VM instance using ssh:

    gcloud compute ssh VM_NAME
    
  2. On the VM instance, install dbus:

    sudo apt-get install dbus
    
  3. Restart logind:

    sudo systemctl restart systemd-logind.service
    

What's next