A small command-line tool for managing a single Google Compute Engine VM you use as a development or work machine. It can check the instance's status, start it on demand, wait for SSH to become available, and then drop you into an SSH session.
gvm is intentionally minimal: it targets exactly one instance (identified by name) in one project, configured entirely through environment variables.
gvm status— print whether the instance isRUNNINGorSTOPPED.gvm start— start the instance (if it isn't already running), wait for it to accept SSH connections, and then SSH in.gvm ssh— SSH directly to the instance's current IP without touching its power state.
Any extra arguments after the subcommand are passed through to ssh, so you can do things like gvm ssh -- ls ~ or gvm start -- tmux attach.
You need a recent Rust toolchain (stable) and Cargo.
Install the latest published release directly with Cargo:
cargo install gce-vmThis will download, build, and place the gvm binary in Cargo's bin directory (usually ~/.cargo/bin). Make sure that directory is on your PATH.
To upgrade to a newer version later:
cargo install gce-vm --forceClone the repository and build it yourself:
git clone <this-repo>
cd gvm
cargo build --releaseThe resulting binary will be at target/release/gvm. Copy or symlink it onto your PATH, e.g.:
install -m 0755 target/release/gvm ~/.local/bin/gvmOr install straight from the source directory:
cargo install --path .gvm uses Google Cloud application default credentials. Before running it, make sure one of the following is true:
GOOGLE_APPLICATION_CREDENTIALSpoints to a service account key file, or- You've run
gcloud auth application-default loginto create user credentials at the default location (~/.config/gcloud/application_default_credentials.jsonon Linux/macOS,%APPDATA%\gcloud\application_default_credentials.jsonon Windows).
If neither is present, gvm refuses to run and tells you how to fix it.
The credentials you use must have sufficient permissions on the target project to list, get, and start Compute Engine instances — for example the roles/compute.instanceAdmin.v1 role, or a tighter custom role with compute.instances.list, compute.instances.get, and compute.instances.start.
All configuration is read from environment variables.
| Variable | Required for | Description |
|---|---|---|
GOOGLE_CLOUD_PROJECT |
all commands | GCP project ID that owns the instance. |
GVM_INSTANCE |
all commands | Name of the Compute Engine instance. |
GVM_USER |
ssh, start |
Local username on the VM to SSH as. |
GVM_START_TIMEOUT |
start (optional) |
Seconds to wait for SSH to come up. Default: 180. |
GOOGLE_APPLICATION_CREDENTIALS |
optional | Path to a service account key file. |
gvm looks the instance up via the aggregated list, so you don't have to specify its zone — it's discovered automatically.
export GOOGLE_CLOUD_PROJECT=my-gcp-project
export GVM_INSTANCE=dev-box
export GVM_USER=alicegvm <start|status|ssh> [args...]Prints RUNNING or STOPPED (anything other than RUNNING is reported as STOPPED).
$ gvm status
RUNNINGStarts the instance if necessary, polls until it's RUNNING and TCP port 22 is reachable, then execs into an SSH session. If the instance is already running it skips straight to the SSH step.
$ gvm start
Starting instance `dev-box` in zone us-central1-a (current status: TERMINATED)...
instance status: PROVISIONING
instance status: STAGING
instance status: RUNNING
probing SSH on 34.123.45.67:22 ...
SSH is ready on 34.123.45.67
Connecting to alice@34.123.45.67 (instance `dev-box` in zone us-central1-a)You can pass extra arguments through to ssh:
gvm start -- -A # forward your SSH agent
gvm start -- tmux attach # run a command instead of an interactive shellIf the instance doesn't become reachable within GVM_START_TIMEOUT seconds, gvm exits with an error.
SSH to the instance at its current IP without trying to start it. Useful when you know it's already running and don't want the extra status polling.
gvm ssh
gvm ssh -- uptimeFor both ssh and start, gvm:
- Prefers the first external (NAT) IP on any network interface's access config.
- Falls back to the first network interface's internal IP if no external IP is present.
If neither is available, the ssh subcommand fails with an error.
gvm statusexits0on success.gvm sshandgvm startpropagatessh's exit code.- Any configuration or API error causes a non-zero exit with a message on stderr.
GVM_INSTANCE environment variable is not set.— export the variables listed under Configuration.No Google Cloud credentials found.— rungcloud auth application-default loginor pointGOOGLE_APPLICATION_CREDENTIALSat a valid key file.- **
instance \X` not found in project `Y`** — double-checkGVM_INSTANCEandGOOGLE_CLOUD_PROJECT`; the instance must exist somewhere in the project's aggregated list. timed out after Ns waiting for ... to accept SSH— the VM started but port 22 didn't open in time. IncreaseGVM_START_TIMEOUT, or check firewall rules / sshd on the instance.
MIT