Skip to content

This Terraform module simplifies the deployment of self-hosted GitHub Actions runners on any Kubernetes cluster. It uses the official Actions Runner Controller (ARC) to create and manage auto-scaling runner sets.

License

Notifications You must be signed in to change notification settings

vmvarela/terraform-github-actions-runner-scale-set

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GitHub Actions Runner Scale Set on Kubernetes

Terraform module that deploys self-hosted GitHub Actions runners on Kubernetes using the official Actions Runner Controller (ARC).

This module automates the deployment of:

  • ARC Controller: Manages the lifecycle of runner scale sets
  • Runner Scale Sets: Auto-scaling GitHub Actions runners
  • Runner Groups: Organized runner access control (optional)
  • Authentication: Support for both GitHub Apps and Personal Access Tokens

Features

  • âś… Multiple scale sets with independent configurations
  • âś… Auto-scaling runners (min/max configuration)
  • âś… GitHub App or PAT authentication
  • âś… Private container registry support
  • âś… Runner group management with repository and workflow restrictions
  • âś… Flexible runner image configuration
  • âś… Container mode support (Docker-in-Docker or Kubernetes)
  • âś… Automatic namespace creation

Usage

Basic Example

module "github_runners" {
  source  = "path/to/module"

  github_org   = "my-organization"
  github_token = var.github_token
}

Complete Example with Multiple Scale Sets

module "github_runners" {
  source = "path/to/module"

  github_org   = "my-organization"
  github_token = var.github_token

  controller = {
    name             = "arc-controller"
    namespace        = "arc-system"
    create_namespace = true
    version          = "0.13.0"
  }

  scale_sets = {
    "default-runners" = {
      namespace           = "arc-runners-default"
      create_namespace    = true
      min_runners         = 1
      max_runners         = 10
      runner_image        = "ghcr.io/actions/actions-runner:latest"
      container_mode      = "dind"
      visibility          = "all"
      create_runner_group = true
    }

    "production-runners" = {
      namespace           = "arc-runners-prod"
      create_namespace    = true
      min_runners         = 2
      max_runners         = 20
      runner_group        = "production"
      visibility          = "selected"
      repositories        = ["repo1", "repo2"]
      create_runner_group = true
    }

    "ci-runners" = {
      namespace           = "arc-runners-ci"
      create_namespace    = true
      min_runners         = 3
      max_runners         = 15
      runner_group        = "ci"
      visibility          = "selected"
      workflows           = [".github/workflows/ci.yml"]
      create_runner_group = true
    }
  }
}

GitHub App Authentication

module "github_runners" {
  source = "path/to/module"

  github_org                 = "my-organization"
  github_app_id              = 123456
  github_app_installation_id = 789012
  github_app_private_key     = file("${path.module}/github-app-key.pem")
}

Private Container Registry

module "github_runners" {
  source = "path/to/module"

  github_org   = "my-organization"
  github_token = var.github_token

  private_registry          = "registry.example.com"
  private_registry_username = var.registry_username
  private_registry_password = var.registry_password

  scale_sets = {
    "custom-image-runners" = {
      runner_image = "registry.example.com/custom/runner:latest"
    }
  }
}

Requirements

Name Version
terraform >= 1.0
github ~> 6.0
helm ~> 3.0
kubernetes ~> 2.0

Providers

Name Version
github ~> 6.0
helm ~> 3.0
kubernetes ~> 2.0

Resources

Name Type
github_actions_runner_group.this resource
helm_release.controller resource
helm_release.scale_set resource
kubernetes_namespace.controller resource
kubernetes_namespace.scale_set resource
kubernetes_secret.github_creds resource
kubernetes_secret.private_registry_creds resource
github_repositories.all data source

Inputs

Name Description Type Default Required
github_org GitHub organization name string n/a yes
controller Controller configuration
object({
name = optional(string, "arc")
namespace = optional(string, "arc-systems")
create_namespace = optional(bool, true)
version = optional(string, "0.13.0")
})
{
"name": "arc",
"namespace": "arc-systems",
"create_namespace": true,
"version": "0.13.0"
}
no
scale_sets Scale sets configuration (map)
map(object({
runner_group = optional(string, null)
create_runner_group = optional(bool, true)
namespace = optional(string, "arc-runners")
create_namespace = optional(bool, true)
version = optional(string, "0.13.0")
min_runners = optional(number, 1)
max_runners = optional(number, 5)
runner_image = optional(string, "ghcr.io/actions/actions-runner:latest")
pull_always = optional(bool, true)
container_mode = optional(string, "dind")
visibility = optional(string, "all")
workflows = optional(list(string), null)
repositories = optional(list(string), null)
}))
{
"arc-runner-set": {
"runner_group": null,
"create_runner_group": true,
"namespace": "arc-runners",
"create_namespace": true,
"version": "0.13.0",
"min_runners": 1,
"max_runners": 5,
"runner_image": "ghcr.io/actions/actions-runner:latest",
"pull_always": true,
"container_mode": "dind",
"visibility": "all",
"workflows": null,
"repositories": null
}
}
no
github_token GitHub Token (use either token or GitHub App credentials) string null no
github_app_id GitHub App ID (use either token or GitHub App credentials) number null no
github_app_installation_id GitHub App Installation ID number null no
github_app_private_key GitHub App private key (PEM format) string null no
github_repositories All repositories in the organization. If not provided, they will be fetched by the module any null no
private_registry Private container registry URL string null no
private_registry_username Private container registry username string null no
private_registry_password Private container registry password string null no

Outputs

Name Description
controller The Helm release name of the controller
scale_set List of scale set names created

Authentication Methods

This module supports two authentication methods with GitHub:

Personal Access Token (PAT)

module "github_runners" {
  source       = "path/to/module"
  github_org   = "my-organization"
  github_token = var.github_token  # Classic PAT with admin:org scope
}

Required Scopes:

  • admin:org (for runner group management)
  • repo (if managing repository runners)

GitHub App

module "github_runners" {
  source                     = "path/to/module"
  github_org                 = "my-organization"
  github_app_id              = var.github_app_id
  github_app_installation_id = var.github_app_installation_id
  github_app_private_key     = file("github-app-key.pem")
}

Required Permissions:

  • Repository permissions: Actions: Read & Write, Administration: Read & Write
  • Organization permissions: Self-hosted runners: Read & Write

Scale Set Configuration

Container Modes

  • dind (Docker-in-Docker): Runs Docker daemon inside the runner container
  • kubernetes: Uses Kubernetes-native container execution
  • null: No container mode (bare runner)

Visibility Options

  • all: Runners available to all repositories in the organization
  • selected: Runners limited to specific repositories
  • private: Runners available only to private repositories

Runner Groups

Runner groups organize runners and control access:

scale_sets = {
  "backend-runners" = {
    runner_group        = "backend-team"
    create_runner_group = true
    visibility          = "selected"
    repositories        = ["api", "database", "worker"]
    workflows           = [".github/workflows/deploy.yml"]
  }
}

Testing

This module includes comprehensive Terraform native tests using mock providers:

terraform test

Tests cover:

  • Controller creation
  • Multiple scale sets
  • GitHub App authentication
  • Private registry configuration
  • Runner groups
  • Variable validations
  • Container modes
  • Resource dependencies

License

MIT License - see LICENSE for details.

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

Authors

Created and maintained by [Your Name/Organization]

About

This Terraform module simplifies the deployment of self-hosted GitHub Actions runners on any Kubernetes cluster. It uses the official Actions Runner Controller (ARC) to create and manage auto-scaling runner sets.

Topics

Resources

License

Stars

Watchers

Forks

Languages