Turn Your Vehicle Into a Smart Earning Asset

While you’re not driving your car or bike, it can still be working for you. MOTOSHARE helps you earn passive income by connecting your vehicle with trusted renters in your city.

🚗 You set the rental price
🔐 Secure bookings with verified renters
📍 Track your vehicle with GPS integration
💰 Start earning within 48 hours

Join as a Partner Today

It’s simple, safe, and rewarding. Your vehicle. Your rules. Your earnings.

How to Install and Configure GitHub Self-Hosted Runners Using Ansible



🚀 1. Introduction

GitHub Actions self-hosted runners let you run CI/CD jobs on your own machines instead of GitHub-hosted ones.
Using Ansible, you can automate the installation, registration, and management of runners across multiple servers—securely and repeatably.

This tutorial covers:

  • What GitHub Runners are
  • Why use Ansible to manage them
  • Installation prerequisites
  • Step-by-step setup (two methods)
  • Real Ansible playbooks (systemd and Docker)
  • Troubleshooting and best practices

🧠 2. What is a GitHub Runner?

A GitHub Actions Runner is an agent process that runs your CI/CD jobs from GitHub.
When a workflow is triggered, GitHub dispatches jobs to available runners.

You can host runners:

  • GitHub-Hosted: Managed by GitHub (default)
  • Self-Hosted: You install and manage them (ideal for custom hardware, private environments, or cost control)

⚙️ 3. Why Use Ansible for Runners

Manually registering and configuring self-hosted runners is tedious and error-prone.
Ansible simplifies this by:

✅ Automating installation & upgrades
✅ Managing multiple runners or servers
✅ Handling registration tokens & environment variables securely
✅ Supporting repeatable, idempotent deployments
✅ Integrating easily with CI/CD pipelines or infrastructure as code


🧩 4. Architecture Options

You have two main ways to deploy runners:

TypeManaged BySuitable ForIsolationExample Role
Systemd (Host)OS serviceLong-lived runnersSharedMonolithProjects
Containerized (Docker)Docker containersEphemeral/Scalable runnersHighcompscidr

🧰 5. Prerequisites

GitHub Personal Access Token

Create a token (PAT) with the repo and admin:org or workflow scopes depending on whether it’s repo- or org-level.

GitHub → Settings → Developer Settings → Personal Access Tokens → “Fine-grained tokens” or “Classic” → Enable scopes:

  • repo
  • admin:org
  • workflow

Export it on your control node:

export GH_PAT="ghp_xxxxxxxxxxxxxxxxxxxxx"
Code language: JavaScript (javascript)

Ansible Installed

pip install ansible

Target Hosts

  • RHEL / CentOS / Ubuntu with Python installed
  • SSH access from control node

🧱 6. Option A: Systemd Runners (Recommended for VM/Server)

We’ll use MonolithProjects/ansible-github_actions_runner.

Step 1: Install the Role

ansible-galaxy role install git+https://github.com/MonolithProjects/ansible-github_actions_runner.git,1.21.1
Code language: JavaScript (javascript)

or use requirements.yml:

---
roles:
  - name: monolithprojects.github_actions_runner
    src: https://github.com/MonolithProjects/ansible-github_actions_runner
    version: "1.21.1"
Code language: JavaScript (javascript)

then run:

ansible-galaxy install -r requirements.yml
Code language: CSS (css)

Step 2: Create Your Inventory

inventory.ini

[github_runners]
runner1 ansible_host=192.168.56.10 ansible_user=ec2-user

Step 3: Write the Playbook

install_runner.yml

- name: Install GitHub Runner via Ansible (Systemd)
  hosts: github_runners
  become: true

  vars:
    github_account: "my-org-or-user"
    github_repo: "my-repo"          # optional if org-level
    runner_user: "runner"
    runner_labels:
      - linux
      - ansible
    runner_state: present
    github_token: "{{ lookup('env','GH_PAT') }}"  # use env variable

  roles:
    - monolithprojects.github_actions_runner
Code language: PHP (php)

Step 4: Run the Playbook

ansible-playbook -i inventory.ini install_runner.yml
Code language: CSS (css)

✅ This installs, registers, and enables the runner as a systemd service.
Check the service:

sudo systemctl status actions.runner*
Code language: CSS (css)

Step 5: Verify on GitHub

Go to
Repo → Settings → Actions → Runners
→ You’ll see the new runner with your label and status = online.


🐳 7. Option B: Dockerized Runners (for High Density & Isolation)

We’ll use compscidr/ansible-github-runner.

Step 1: Install Role

ansible-galaxy role install compscidr.github_runner
Code language: CSS (css)

Make sure Docker is available on your hosts:

ansible -m apt -a "name=docker.io state=present" all
Code language: JavaScript (javascript)

Step 2: Create Inventory

inventory.ini

[docker_runner_hosts]
runner2 ansible_host=192.168.56.11 ansible_user=ubuntu

Step 3: Playbook

docker_runner.yml

- name: Install Dockerized GitHub Runner
  hosts: docker_runner_hosts
  become: true
  vars:
    github_owner: "my-org-or-user"
    github_repo: "my-repo"
    github_token: "{{ lookup('env','GH_PAT') }}"
    github_runner_count: 3                 # creates 3 runners (containers)
    github_runner_labels:
      - docker
      - self-hosted
    github_runner_image: "ghcr.io/myoung34/github-runner:latest"
    github_runner_workdir: "/tmp/runner"
  roles:
    - compscidr.github_runner
Code language: PHP (php)

Step 4: Run Playbook

ansible-playbook -i inventory.ini docker_runner.yml
Code language: CSS (css)

This will:

  • Pull the container image
  • Register each container runner with GitHub
  • Start them automatically via Docker

Step 5: Validate

List containers:

docker ps

Check runners online at
GitHub → Settings → Actions → Runners


🧰 8. Option C: Minimal Role (rolehippie)

Use if you want lightweight manual control.

ansible-galaxy role install rolehippie.github_runner
Code language: CSS (css)

Playbook

- name: Minimal GitHub Runner Setup
  hosts: all
  become: true
  vars:
    runner_workdir: /opt/actions-runner
    runner_labels: ["linux","self-hosted"]
    runner_repo: "my-org-or-user/my-repo"
    runner_token: "{{ lookup('env','RUNNER_REG_TOKEN') }}"
  roles:
    - rolehippie.github_runner
Code language: JavaScript (javascript)

Note: You must manually fetch a runner registration token using the GitHub REST API or UI before running this playbook.


🧪 9. Validating the Runner

Once playbooks finish:

  1. Log in to your GitHub repo/org
    Settings → Actions → Runners
  2. Verify status shows “Online”
  3. Run a test workflow using your label:
name: Test Runner
on: [push]
jobs:
  test:
    runs-on: [self-hosted, ansible]
    steps:
      - run: echo "Hello from self-hosted runner!"
Code language: PHP (php)

10. Updating or Removing a Runner

To remove:

runner_state: absent
Code language: HTTP (http)

Then re-run your playbook — it unregisters and stops the service.


🧭 11. Troubleshooting

ProblemPossible Fix
Runner not appearing in GitHubCheck token validity and scopes
Runner shows offlineCheck network and systemd logs
Docker containers exit quicklyVerify PAT and environment variables
“Permission denied”Ensure become: true or correct user privileges
Multiple runners overwrite each otherUse unique names or containerized approach

🔐 12. Best Practices

✅ Use Personal Access Tokens (PAT), not registration tokens in playbooks
✅ Store tokens in Ansible Vault (ansible-vault encrypt_string)
✅ Use labels to route jobs cleanly
✅ Pin runner versions for reproducibility
✅ Use Dockerized runners for ephemeral workloads
✅ Rotate tokens periodically


🏁 13. Summary

Deployment TypeBest ForExample Role
Systemd RunnerLong-lived VM runnersMonolithProjects
Dockerized RunnerScalable, short-lived runnerscompscidr
Minimal DIYCustom/light setupsrolehippie

📘 14. References


In summary:
If you’re new to self-hosted runners—start with MonolithProjects (simple and reliable).
If you need scale and isolation—use compscidr (Dockerized).
For ultimate control and minimal overhead—rolehippie is fine for tinkering.


Subscribe
Notify of
guest
1 Comment
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
Jason Mitchell
Jason Mitchell
5 days ago

This article delivers a clear and practical explanation of how to use Ansible to set up GitHub self-hosted runners — automating what would otherwise be a tedious, manual process. I like how it outlines each step and the configuration required, making it much easier for DevOps teams to replicate across multiple hosts. The guide makes a strong case for why using infrastructure-as-code tools like Ansible boosts consistency, repeatability, and reduces the risk of human error in CI/CD setups. For anyone managing build automation or custom deployment pipelines, this post is a valuable resource that can save time and improve reliability.

Certification Courses

DevOpsSchool has introduced a series of professional certification courses designed to enhance your skills and expertise in cutting-edge technologies and methodologies. Whether you are aiming to excel in development, security, or operations, these certifications provide a comprehensive learning experience. Explore the following programs:

DevOps Certification, SRE Certification, and DevSecOps Certification by DevOpsSchool

Explore our DevOps Certification, SRE Certification, and DevSecOps Certification programs at DevOpsSchool. Gain the expertise needed to excel in your career with hands-on training and globally recognized certifications.

1
0
Would love your thoughts, please comment.x
()
x