Start, stop, restart and terminate a server
Control the power state of a discovered cloud instance from Cushy — start, stop and restart on AWS, GCP, Azure and Alibaba — and understand the two different ways a server gets deleted depending on whether Terraform manages it.
Cushy can change the power state of any compute instance it discovered in a connected cloud account: Start, Stop and Restart. It calls the cloud provider's own API using the same short-lived, keyless credentials it already uses to read your inventory — there is no separate credential and no agent on the machine.
Where the controls are
- Inventory — each live compute row carries
▶ Start,■ Stopand⟳ Restart. - Resource detail — the same controls sit in the header under Power.
You need the `mutate_infra` capability (Deployer, SRE · Cloud Admin or Org Admin). A Viewer sees the inventory row without the buttons — and the API returns 403 regardless, because hiding a button is a convenience, not the security boundary.
What each action actually calls
| Cloud | Start | Stop | Restart |
|---|---|---|---|
| AWS | StartInstances | StopInstances | RebootInstances |
| GCP | instances.start | instances.stop | instances.reset |
| Azure | virtualMachines/start | virtualMachines/deallocate | virtualMachines/restart |
| Alibaba | StartInstance | StopInstance | RebootInstance |
Azure distinguishes power off (the VM is stopped but still allocated — and still billed for compute) from deallocate (the compute charge stops). Cushy's Stop deallocates, which is what the Azure portal's Stop does and what an operator almost always means. Alibaba's Terminate passes Force=true, because ECS otherwise refuses to delete a running instance.
Why the state says “stopping” and not “stopped”
Stopping a server is not instant. After a successful call Cushy records the transitional state and says where it came from:
- Reported by the provider — AWS answers synchronously with the instance's real current state (
stopping,pending,shutting-down), so that is what you see. - Requested — GCP, Azure and Alibaba answer with an asynchronous operation and no state. Cushy records the documented transition for that action and labels it as requested.
The row's status shows anomaly (a transitional state is genuinely unsettled), then settles to healthy or read-only when the next inventory sync reads the real state back from the cloud. Cushy never writes a final state it did not observe.
Deleting a server — two different paths
This is the part worth reading carefully, because which affordance you get depends on whether the instance is under Terraform management.
| The instance is… | How you delete it | Why |
|---|---|---|
| Managed by a Terraform folder | Destroy… on the row (plan destroy → approve → apply) | Terraform holds state for it. Deleting it behind Terraform's back would leave the state describing a server that no longer exists, and would be a second, unreviewed way to destroy managed infrastructure. |
| Unmanaged (discovered only) | ⨯ Terminate… on the row (typed-name confirm) | There is no Terraform state to desync and no plan to run, so a direct provider call is the only honest way to remove it. |
A direct terminate deletes the instance in your cloud account. It is gated three ways: it needs the cloud-account management role (a Deployer's deploy permission is not enough), you must type the instance name exactly, and the API additionally requires an explicit ack. On success Cushy soft-deletes the inventory row — the record is retained for audit, never purged.
If you try to terminate a Terraform-managed instance the API answers 409 and names the right path. If you genuinely want a direct terminate, Unmanage it from its folder first — which is itself an explicit, audited act.
Power on a managed instance is fine
Start, stop and restart are allowed on Terraform-managed instances too. Instance power is a runtime state, not managed configuration — stopping a server does not change its Terraform definition and does not show up as drift.
Errors you may see
| Situation | What Cushy answers |
|---|---|
| The connector role cannot start/stop instances | The provider's own permission error, naming the exact missing action — never a fake success |
| The resource is not a compute instance | 400 — lifecycle actions apply to compute only |
| The row is a pending Terraform draft or a failed deploy | 400 — nothing is running in the cloud yet |
| The cloud account is disconnected | 409 — reconnect it first |
| Restarting an instance that is stopped | The provider refuses; start it instead |
| The cloud is throttling | 429, with the provider's retry hint |
Audit
Every action is recorded as cloud.instance_started, cloud.instance_stopped, cloud.instance_restarted or cloud.instance_terminated, with the operator, the instance, its provider and region, and the resulting state — including whether that state was reported by the provider or requested. Denied attempts are recorded as cloud.rbac_denied.
Current limits
- Compute instances only — stopping a managed database, a Kubernetes node pool or a scale set is not offered.
- No scheduled or policy-driven power management (for example nightly shutdowns).
- No hibernate or suspend.
- Cushy does not poll the cloud's async operation to completion; the next inventory sync reports the settled state.