GitHub Actions runners with Terraform
When a build needs a specific Linux setup, you can give GitHub Actions a machine with the CPU, memory, and tools you choose. GitHub sends the job to a runner process on that machine.
This recipe uses the Dedalus Terraform provider to create the machine and register its runner. A separate GitHub-hosted job deletes the machine afterward, so cleanup can finish even after the runner is gone.
The example repository contains the Terraform configuration, runner setup, and workflow. Its first job prints the machine's operating system and filesystem information. Replace those steps with your build once you have verified the full run.
Set up your repository
Fork dedalus-labs/cookbook, enable Actions in your fork, and clone it. Install Terraform 1.5 or later, Go, make, jq, and the GitHub CLI. Authenticate gh with administrator access to your fork.
git clone https://github.com/YOUR_ACCOUNT/cookbook.git
cd cookbook/examples/github-actions-runner
export TF_VAR_github_repo=YOUR_ACCOUNT/cookbook
export DEDALUS_BASE_URL=https://dcs.dedaluslabs.ai
export DEDALUS_API_KEY=your-api-key
TF_VAR_github_repo tells Terraform where to register the runner. The provider reads DEDALUS_API_KEY and DEDALUS_BASE_URL from your shell. Keep the key out of Terraform source files.
Create the runner
make init
make apply
make verify REPO="$TF_VAR_github_repo"
Review the Terraform plan before approving it. The configuration requests 2 vCPUs, 4 GiB of memory, and 20 GiB of storage. It disables autosleep so the machine stays awake while it waits for a job. make verify checks that GitHub reports the runner as online.
Run the job
The cleanup job needs the machine ID and API address because it runs on another machine. Store those as repository variables, then add DEDALUS_API_KEY as a repository secret when prompted:
gh variable set DM_MACHINE_ID --repo "$TF_VAR_github_repo" \
--body "$(terraform -chdir=terraform output -raw machine_id)"
gh variable set DEDALUS_BASE_URL --repo "$TF_VAR_github_repo" \
--body "$DEDALUS_BASE_URL"
gh secret set DEDALUS_API_KEY --repo "$TF_VAR_github_repo"
gh workflow run github-actions-runner.yml --repo "$TF_VAR_github_repo"
gh run list --workflow github-actions-runner.yml --repo "$TF_VAR_github_repo"
The workflow sends hello-from-dm to a runner labeled [self-hosted, dedalus]. After that job, teardown runs on ubuntu-latest with if: always() and calls the DCS API to delete the machine.
Check both jobs in GitHub. To change the build steps, edit ci/github-actions-runner.ts and regenerate the workflow with Hollywood, following the repository's instructions.
Run it again or clean up
Run one workflow at a time. The cleanup job reads a shared machine ID, so overlapping runs could delete a machine that another job still needs.
After a run deletes its machine, run make apply again and update DM_MACHINE_ID before starting another workflow. If automatic cleanup did not finish, delete the machine from your checkout:
make destroy
Confirm deletion because autosleep is disabled. Compute is billed while the machine is awake, and storage remains billable until deletion. See pricing for rates.
The example puts the runner and its workspace on a 2 GiB filesystem backed by memory. That workspace resets on boot. Builds that need more space or persistent caches must use the machine's persistent storage.
