Skip to content
Manual revision 01 · GitHub.com · Linux x64 and ARM64 · AWS

Operations

Prove the control plane before trusting it.

Readiness is generation-scoped. A controller revision becomes healthy only after it owns the lease, validates every GitHub session, completes a poll, and reconciles capacity for every fleet.

Health is layered

SignalWhat it provesWhat it does not prove
/healthzThe process and local HTTP server are aliveLeadership, GitHub connectivity, or fleet operation
/readyzThe current controller generation completed startup proofThat every later job launch will succeed
/versionThe running build identityThat Terraform points at the intended image digest
FleetReadyThe current per-fleet listener and reconciliation stateThat workflow code itself will pass
Disposable jobAssignment, launch, registration, execution, and terminationEvery workload-specific dependency or permission

The HTTP endpoints are local controller interfaces used by ECS health checks. Gondola requires no public inbound endpoint. Treat an ECS task in RUNNING state as liveness, not readiness.

Signals to monitor

Structured CloudWatch logs and cost tags are always present. Custom metrics and alarms are opt-in because they add recurring CloudWatch charges.

SignalWhat it answers
FleetReadyIs each fleet’s current listener and reconciliation path operational?
AssignedJobs / CompletedJobsAre queued assignments becoming completed work?
ActiveRunners / RunnerLaunchesHow much capacity exists and how often the fleet creates it.
RunnerLaunchLatency / JobStartLatencyWhether cloud capacity or runner registration is delaying jobs.
RunnerLaunchErrorsAre EC2, subnet, quota, image, or permission failures preventing capacity?
RunnerTerminationErrorsAre disposable runners being retired cleanly?
RunnerReconcileErrorsIs periodic desired-versus-actual cleanup failing?
SpotFallbacksHow often is the fleet moving from Spot to On-Demand?

Metrics use deployment and fleet dimensions; capacity-specific events also identify Spot or On-Demand. Publishing is asynchronous and bounded so a CloudWatch slowdown cannot block runner reconciliation. Whenmetrics_enabled and alarms_enabled are true, Terraform creates a readiness alarm plus launch, termination, and reconcile error alarms for each fleet. Notification actions remain customer-selected.

Operating cadence

CadenceReview
ContinuouslyController readiness, per-fleet errors, queue delay, and non-terminating instances
WeeklySpot fallback, EC2/EBS spend, log ingestion, stale GitHub runners, and quota headroom
Each releaseDigests, SBOM/checksums, Terraform plan, one acceptance job per fleet, rollback path
Each credential rotationNew secret version, generation nonce, fleet readiness, old-key revocation, audit events
QuarterlyController loss, coordination-table recreation, key rotation, rollback, and full runner cleanup

Upgrade procedure

  1. Select the new controller by exact OCI digest and keep the previous digest available.
  2. Review terraform plan for the intended task-definition and launch-template generation.
  3. Schedule a short new-job scheduling window, then apply. Already-running EC2 jobs continue.
  4. Wait for the new generation to acquire leadership and prove every fleet.
  5. Run a disposable job on each fleet and verify runner termination.

A new generation does not borrow the old generation’s readiness. New GitHub jobs may queue briefly while leadership hands off; already running EC2 jobs do not depend on the controller revision and continue. Terraform waits for ECS steady state by default.

If the new generation cannot initialize, the ECS deployment circuit breaker can restore the prior task definition. To reconcile Terraform intentionally, restore the previous digest and apply it.

Incident triage

  1. Check ECS desired, running, and pending task counts plus deployment state.
  2. Inspect readiness, recent per-fleet transitions, and structured logs.
  3. Confirm the DynamoDB coordination item has one unexpired owner. Do not edit a live lease.
  4. Inspect GitHub queue/App permissions and matching tagged EC2 instances.
  5. Check Spot capacity, subnet addresses, service quotas, Secrets Manager, DynamoDB, and GitHub API errors before changing fleet policy.

Preserve the first error and avoid broad policy changes during triage. The deployment name, generation, fleet, GitHub job ID, EC2 instance ID, and UTC timestamps are the safest cross-system correlation keys.

A runner also has an independent hard-expiry timer. Manually terminate an instance only after confirming its job is no longer active, and retain the instance and job identifiers for review.

Rotate the GitHub App key

Create a new key and Secrets Manager version. When the ARN remains unchanged, set a new deployment_generation_nonce so ECS starts tasks that read the new value. Verify every fleet on that generation before revoking the old key.

  1. Create a new App key without revoking the old key.
  2. Store it as a new secret version and record the rotation event.
  3. Change deployment_generation_nonce when the ARN stays the same, then apply Terraform.
  4. Verify readiness and a disposable job on every fleet.
  5. Revoke the old App key and verify no task still references it.

Recovery responsibilities

StateRecovery sourceAction
Terraform stateProtected, versioned customer backendRestore before any apply; never reconstruct by guesswork
Controller imageSigned release digest or customer ECR copyPin the last known-good digest
GitHub App keyCustomer rotation procedureIssue a new key when integrity is uncertain
Coordination tableNo backup requiredRecreate empty; never restore an old lease
Runner instancesNo recovery sourceTreat as disposable; terminate or allow hard expiry
GitHub scale setKnown Terraform/runtime configurationReconcile by owned name or deliberately recreate after drain

Decommission

  1. Drain queued work and scale the ECS service to zero.
  2. Delete each Gondola-owned GitHub scale set with the explicit deletion command and matching deployment ID.
  3. Run terraform destroy with the exact state for this deployment.
  4. Verify no tagged EC2/EBS resources, secret, table, log group, or scale-set registration remains.

Next

Troubleshoot by lifecycle

Find the first failed handoff without destroying the evidence.