Architecting On-Premise Automation with GitHub Actions Self-Hosted Runners

The transition from legacy version control systems, such as Team Foundation Server (TFS), to modern GitHub Enterprise environments necessitates a robust strategy for continuous integration and continuous deployment (CI/CD), particularly when the target deployment environment is not a cloud provider. While contemporary tutorials frequently emphasize deployments to Azure or AWS, the operational reality for many enterprises involves deploying artifacts to on-premise servers. GitHub Actions facilitates this requirement through the implementation of self-hosted runners, allowing organizations to execute workflows on their own private infrastructure. This capability bridges the gap between the cloud-based orchestration of GitHub and the physical or virtualized constraints of a private data center, ensuring that build artifacts can be moved from the source of truth to the production server without exposing internal network resources to the public internet.

The Fundamental Architecture of Self-Hosted Runners

GitHub Actions provides two primary execution environments: GitHub-hosted runners and self-hosted runners. While both are built upon the same open-source software and support the same primary operating systems—Linux, macOS, and Windows—their administrative and operational profiles differ significantly. GitHub-hosted runners are fully managed virtual machines provided by GitHub, offering a "zero-maintenance" experience. In contrast, self-hosted runners are installed and managed by the user on their own infrastructure.

This architectural choice is critical for organizations migrating from TFS or other legacy systems because it allows the runner to reside within the same network security zone as the target on-premise servers. When a runner is installed on a local server, it creates a secure outbound connection to GitHub to poll for new jobs. Once a job is assigned, the runner executes the defined steps locally. Because the runner is already inside the corporate firewall, it can interact with local databases, internal file shares, and proprietary on-premise servers using internal IP addresses and DNS names, bypassing the need to open inbound firewall ports for the GitHub cloud.

Strategic Comparison of Runner Environments

Choosing between hosted and self-hosted infrastructure involves balancing convenience against control. The following table outlines the core distinctions based on enterprise requirements.

Feature GitHub-Hosted Runners Self-Hosted Runners
Management Fully managed by GitHub Managed by the organization
Infrastructure GitHub's Cloud VMs On-prem VMs, Containers, or Cloud
OS Support Linux, macOS, Windows, ARM, GPU Linux, macOS, Windows
Network Access Public Internet Private Network / Intranet
Configuration Pre-configured Fully Customizable
Scaling Automatic User-defined or via ARC

Scaling On-Premise Infrastructure with ARC and Scale Sets

For organizations with significant Kubernetes expertise, GitHub recommends the Actions Runner Controller (ARC). ARC is a production-ready autoscaling solution that manages the full lifecycle of runners within a Kubernetes cluster. This includes the automated provisioning of runners, the execution of jobs, and the subsequent cleanup of resources once a job is complete.

For those requiring more granular control beyond standard Kubernetes deployments, the GitHub Actions Runner Scale Set Client provides a Go-based module. This client is designed for platform teams and infrastructure providers to build custom autoscaling solutions across a variety of environments:

  • Virtual Machines (VMs)
  • Containers
  • On-premise hardware
  • Cloud services

The Scale Set Client orchestrates the interactions with the GitHub API but leaves the actual infrastructure provisioning to the organization. This allows for the definition of specific creation and destruction logic for runners and the use of multiple labels for flexible job routing. This flexibility ensures that organizations can meet strict compliance constraints and specific operational workflows while maintaining real-time telemetry for every job execution.

Network Configuration and Firewall Requirements

Implementing self-hosted runners on-premise requires precise network configuration to ensure the runner can communicate with GitHub's services. Since the runner initiates an outbound connection, the firewall must allow traffic to specific domains.

The following domains are mandatory for essential operations:

  • github.com
  • api.github.com
  • *.actions.githubusercontent.com

To support the full lifecycle of a workflow, including the downloading of actions and the management of artifacts, the following endpoints must be accessible:

  • For downloading actions: codeload.github.com
  • For job summaries, logs, workflow artifacts, and caches: results-receiver.actions.githubusercontent.com and *.blob.core.windows.net
  • For runner version updates: objects.githubusercontent.com, objects-origin.githubusercontent.com, github-releases.githubusercontent.com, and github-registry-files.githubusercontent.com
  • For OIDC tokens: *.actions.githubusercontent.com
  • For GitHub Packages and containers: *.pkg.github.com, pkg-containers.githubusercontent.com, and ghcr.io
  • For Git Large File Storage (LFS): github-cloud.githubusercontent.com and github-cloud.s3.amazonaws.com
  • For Dependabot updates: dependabot-actions.githubapp.com
  • For release assets: release-assets.githubusercontent.com
  • For VNet requirements: api.snapcraft.io

Organizations utilizing IP address allow lists for their GitHub Enterprise accounts must specifically add the public IP address of their self-hosted runner to the allow list to prevent communication failures.

Advanced Deployment Strategies and Security

When deploying to on-premise servers, security and isolation are paramount. One high-impact strategy is the use of ephemeral runners. An ephemeral runner is configured to be destroyed immediately after a single job is completed. This creates a short-lived compute environment for every job on demand.

The impact of ephemeral runners is twofold:

  1. Security: Per-build isolation reduces the risk of data leakage in multi-tenanted environments, as no state is persisted from one job to the next.
  2. Performance: Because a new environment is created for every job, there is no need for a job to wait for an idle runner, which simplifies the overall auto-scaling logic.

For organizations that integrate their on-premise runners with cloud identity providers, such as AWS, GitHub Actions provides an OIDC provider. This allows the runner to obtain short-lived credentials without storing long-term secrets on the runner itself. When scaling this across many repositories, organizations can avoid IAM role limits by using:

  • Attribute Based Access Control (ABAC): Matching claims in the GitHub token (like repository name or branch) to AWS resource tags.
  • Role Based Access Control (RBAC): Grouping repositories into Teams to reduce the total number of required roles.
  • Identity Broker Patterns: Dynamically vending credentials based on the identity provided by the GitHub workflow.

Workflow Automation and Tooling Integration

GitHub Actions is designed to automate the entire software workflow, from the initial idea to final production. This versatility extends to several key features that enhance the on-premise experience:

  • Matrix Builds: This allows developers to test across multiple operating systems and runtime versions simultaneously, ensuring that a build is compatible with various on-premise server configurations.
  • Language Support: The platform natively supports a wide array of languages, including Node.js, Python, Java, Ruby, PHP, Go, Rust, and .NET.
  • GitHub Packages: By pairing Actions with GitHub Packages, teams can simplify package management using the GITHUB_TOKEN for fast distribution via a global CDN and efficient dependency resolution.
  • Live Logs: Real-time execution logs with color and emoji support provide immediate feedback on the status of on-premise deployments.

For those who prefer a managed experience even within their own cloud environment, AWS CodeBuild can be used to provide managed self-hosted runners. This removes the need to maintain the underlying infrastructure or build custom scaling logic, as CodeBuild manages the ephemeral environments and provides low start-up latency.

Conclusion

The transition from legacy systems like TFS to GitHub Actions for on-premise deployment is not merely a change in tooling but a shift in architectural strategy. By leveraging self-hosted runners, organizations can maintain the security and proximity required to interact with internal servers while benefiting from the orchestration capabilities of a modern CI/CD platform. The choice between standard self-hosted runners, ARC for Kubernetes, or managed solutions like AWS CodeBuild depends on the organization's internal expertise and scaling needs. The implementation of ephemeral runners and OIDC-based identity management further secures the pipeline, ensuring that the automation of build, test, and deploy activities does not introduce new security vulnerabilities. Ultimately, the flexibility of the GitHub Actions Runner Scale Set Client empowers platform teams to customize the runner lifecycle, ensuring that on-premise infrastructure can be as agile as any cloud-native environment.

Sources

  1. GitHub Community Discussions
  2. GitHub Documentation: Self-hosted runners
  3. GitHub Features: Actions
  4. GitHub Blog: Choosing Runners
  5. AWS DevOps Blog: Best Practices for Self-Hosted Runners

Related Posts