GitHub Actions Tutorial — Ephemeral Runners

1 minute read

Ephemeral Runners

Ephemeral runners process a single job and then automatically de-register. Each job gets a clean environment — no leftover files, credentials, or state from previous runs.


Why Ephemeral?

Persistent Runner Ephemeral Runner
Keeps state between jobs Clean slate every job
Risk of credential leaks No credentials persist
Disk fills over time Fresh workspace every time
Must clean up manually Automatic cleanup
Faster (no setup) Slightly slower (re-setup)

Configuring Ephemeral Mode

At Registration

./config.sh --url https://github.com/my-org/my-repo \
            --token TOKEN \
            --ephemeral

The --ephemeral flag tells the runner to process one job and then exit.

How It Works

1. Runner starts → registers with GitHub
2. Picks up one queued job
3. Executes the job
4. De-registers → exits
5. Orchestrator restarts a new runner instance

Ephemeral Runners with ARC

ARC runners are ephemeral by default — each Kubernetes pod runs one job:

helm install arc-runner-set \
  --namespace arc-runners \
  oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set \
  --set githubConfigUrl="https://github.com/my-org" \
  --set githubConfigSecret.github_token="ghp_xxxxx" \
  --set minRunners=0 \
  --set maxRunners=10
  # Ephemeral by default in ARC

Ephemeral Runners with VMs

Use cloud VM auto-scaling to create ephemeral runners:

AWS Auto Scaling Group

1. Launch Template with runner setup script
2. Auto Scaling Group: min=0, max=10
3. Lambda function listens for workflow_job webhooks
4. Scales up on 'queued', scales down on 'completed'

User Data Script (AWS EC2)

#!/bin/bash
# Configure and run ephemeral runner
cd /home/runner/actions-runner
./config.sh --url https://github.com/my-org \
            --token "$TOKEN" \
            --ephemeral \
            --unattended
./run.sh
# After job completes, runner exits
# Auto Scaling Group terminates the instance
shutdown -h now

JIT (Just-In-Time) Runners

GitHub also supports JIT runner configuration via the API — generate a one-time config for a specific job:

# API call returns a JIT config token
curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  https://api.github.com/repos/OWNER/REPO/actions/runners/generate-jitconfig \
  -d '{"name":"jit-runner","runner_group_id":1,"labels":["self-hosted","linux"]}'

JIT runners are always ephemeral — they’re configured for exactly one job.


Common Mistakes

Mistake Fix
Runner doesn’t restart after job You need an orchestrator (systemd, K8s, ASG) to restart it
State persists between jobs Ensure --ephemeral flag is set
Slow startup Pre-bake common tools into the runner image
Registration token expires Generate fresh tokens for each runner instance

Quick Reference

Concept Detail
Flag --ephemeral during config.sh
Behavior One job → exit
ARC Ephemeral by default
VMs Combine with auto-scaling groups
JIT API-generated one-time config
Benefit Clean environment, no state leaks

← Previous: Autoscaling (ARC)

Next: Security Considerations →

Updated: