Documentation

VM Autoscaling

Autoscaler policies right-size VM fleets automatically based on utilization metrics and schedule triggers. One policy targets one cloud account + resource selector (tag, group, or a specific autoscaling group/instance-pool) and runs in one of three modes.

Modes

The mode is auto-derived from the credential's permission verdict (see Cloud Accounts). You can downgrade a policy's effective mode but not upgrade it past what the credential can do.

ModeRequired permissionBehaviour
monitorread-onlyCollects metrics and publishes what-if recommendations. No cloud writes.
recommendread-writeGenerates recommendations with a one-click apply button. No automatic writes.
autopilotread-writeApplies changes automatically within the configured min/max/cooldown.

Quick Setup (Smart Defaults)

Pick a cloud account and target, and ZopNight fills in sensible min/max/target and cooldown values based on the last 14 days of utilization.

GET
/autoscaler-policies/smart-defaults

Fetch smart defaults for a target before creating a policy.

Query Parameters

ParameterDescription
cloud_account_idThe cloud account hosting the target
target_typeaws-asg, ecs-service, gcp-mig, azure-vmss, azure-databricks-instance-pool, etc.
target_uidNative identifier of the scaling target
Responsejson
{
  "data": {
    "min": 2,
    "max": 10,
    "targetCPUPercent": 60,
    "cooldownSeconds": 300,
    "basedOn": {
      "windowDays": 14,
      "p95CPUPercent": 58,
      "peakInstances": 9
    }
  }
}

Create Policy

POST
/autoscaler-policies

Create an autoscaler policy.

Requestbash
curl -X POST https://zopnight.com/api/autoscaler-policies \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "web-tier autoscaler",
    "mode": "recommend",
    "cloudAccountID": "ca_abc123",
    "target": {
      "type": "aws-asg",
      "uid": "arn:aws:autoscaling:us-east-1:123456789012:autoScalingGroup:...:autoScalingGroupName/web"
    },
    "min": 2,
    "max": 10,
    "targetCPUPercent": 60,
    "cooldownSeconds": 300,
    "triggers": [
      { "preset": "business-hours", "timezone": "America/New_York" }
    ]
  }'

Schedule Triggers

Autoscaler policies can be shaped by schedule triggers layered on top of the utilization loop. Three presets are built in:

PresetWhat it does
business-hoursRaises min capacity Mon–Fri 08:00–18:00 in the configured timezone
peak-hoursRaises min capacity during a custom window (typically retail peaks / report runs)
weekend-scale-downLowers min capacity Sat/Sun so the utilization loop can shrink the fleet

One-click from recommendations

Recommendation rules RC-ASC-001..RC-ASC-006 propose autoscaler policies for likely targets. Applying one of those recommendations creates a policy in recommend mode so nothing writes to the cloud until you review it.

ECS Services — Adopt or Replace

ZopNight extends the same autoscaler model to AWS ECS services. The wizard inspects existing AWS Application Auto Scaling policies on the target service before doing anything and offers two paths:

  • Adopt — ZopNight takes over the existing scaling policies. Existing min/max are preserved and the schedule wraps around them. Nothing is recreated.
  • Replace — existing policies are removed and ZopNight installs its own. Used when the existing policies don't match your current traffic shape.
GET
/autoscaler-policies/existing-policies

Inspect existing AWS Application Auto Scaling policies on an ECS service before deciding adopt vs replace.

Query: ?target_type=ecs-service&target_uid=service/cluster-prod/api

Responsejson
{
  "data": {
    "policies": [
      {
        "policyName": "scale-up-on-cpu",
        "metric": "ECSServiceAverageCPUUtilization",
        "target": 60,
        "managedBy": "user"
      }
    ],
    "recommendation": "adopt"
  }
}

Source-aware tolerance

ZopNight refuses to silently overwrite anything it can't fully parse. If an existing policy uses a configuration shape ZopNight doesn't recognize, the wizard surfaces it explicitly and forces a manual decision — adopt with caveats, replace, or cancel.

Provision the Autoscaler Infrastructure

Before the first autopilot policy can write to your cloud account, ZopNight needs a small footprint of cloud-side resources (an IAM role + Lambda / Cloud Run shim that the metrics loop calls into). Provisioning is one-time per cloud account.

GET
/autoscaler-policies/required-permissions

List the IAM permissions ZopNight needs to provision the autoscaler infrastructure for a given cloud account.

Responsejson
{
  "data": {
    "provider": "aws",
    "permissions": [
      "iam:CreateRole",
      "iam:AttachRolePolicy",
      "lambda:CreateFunction",
      "lambda:UpdateFunctionCode",
      "events:PutRule"
    ]
  }
}
POST
/autoscaler-policies/create-infrastructure

Provision the cloud-side infrastructure for a cloud account.

Requestbash
curl -X POST https://zopnight.com/api/autoscaler-policies/create-infrastructure \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "cloudAccountID": "ca_abc123" }'
GET
/autoscaler-policies/infrastructure-status

Check provisioning status for a cloud account. Poll while a create-infrastructure request is in flight.

Responsejson
{
  "data": {
    "cloudAccountID": "ca_abc123",
    "status": "ready",
    "createdAt": "2026-04-29T08:00:00Z",
    "components": {
      "role": "arn:aws:iam::123456789012:role/zopnight-autoscaler",
      "runtime": "arn:aws:lambda:us-east-1:123456789012:function:zopnight-autoscaler-shim"
    }
  }
}

Lifecycle

POST
/autoscaler-policies/{policyID}/apply

Apply the latest recommendation from a recommend-mode policy.

POST
/autoscaler-policies/{policyID}/pause

Pause evaluation. No recommendations or writes are produced.

POST
/autoscaler-policies/{policyID}/resume

Resume a paused policy.

POST
/autoscaler-policies/{policyID}/remove

Tombstone the policy (soft delete). Past events remain visible.

Policy Events

GET
/autoscaler-policies/{policyID}/events

Per-policy event log: recommendations, applies, pauses, writes, failures.

Responsejson
{
  "data": [
    {
      "id": "ev_001",
      "kind": "recommendation",
      "fromMin": 2, "fromMax": 10,
      "toMin": 4, "toMax": 12,
      "reason": "p95 CPU 72% over last 4h",
      "appliedBy": null,
      "createdAt": "2026-04-20T09:30:00Z"
    },
    {
      "id": "ev_002",
      "kind": "apply",
      "toMin": 4, "toMax": 12,
      "appliedBy": "user@company.com",
      "createdAt": "2026-04-20T09:31:12Z"
    }
  ]
}

List & Filters

GET
/autoscaler-policies

List policies with filter/sort/pagination.

GET
/autoscaler-policies/count

Count policies grouped by status.

GET
/autoscaler-policies/filters

Distinct filter values (modes, targets, cloud accounts) for building UIs.

GET
/autoscaler-policies/{policyID}

Get a single policy, including latest recommendation and current target state.

PUT
/autoscaler-policies/{policyID}

Update min/max/target/cooldown/triggers. Does not switch mode.

DELETE
/autoscaler-policies/{policyID}

Delete a policy (same effect as /remove).