Alternatives to GitHub-hosted runners
Published on October 24, 2024 | Written by Andreas
Are you seeking an alternative to GitHub-hosted runners? Learn about ec2-github-runner, terraform-aws-github-runner, and HyperEnv to self-host runners with the help of EC2 instances. All three solutions run completely in your AWS account, which gives you full control.
Why should you consider an alternative to GitHub-hosted runners?
There are a bunch of reasons to consider an alternative to GitHub-hosted runners:
- Reducing costs
- Utilizing runners with more CPU and memory
- Increasing the disk space
- Accessing private networks (e.g., AWS VPC)
- Customizing the runner by pre-installing software
- Speeding up GitHub Actions
- Support for GitHub Enterprise Server
ec2-github-runner: GitHub action to start and stop an EC2 instance
The idea behind ec2-github-runner is simple: provide a GitHub action to launch and terminate EC2 instances.
The following snippet shows a GitHub workflow using the ec2-github-runner
action to launch and terminate an EC2 instance.
- The GitHub workflow starts.
- The
start-ec2-runner
job launches an EC2 instance. - The EC2 instance registers itself as a self-hosted GitHub runner
- The
build
job runs on the EC2 instance. - The
stop-ec2-runner
job terminates the EC2 instance.
name: ec2-github-runner-example
on: push
jobs:
start-ec2-runner:
name: Start EC2 runner
runs-on: ubuntu-latest # the job runs on GitHub-hosted runners
outputs:
label: ${{ steps.start-ec2-runner.outputs.label }}
ec2-instance-id: ${{ steps.start-ec2-runner.outputs.ec2-instance-id }}
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-1
- name: Start EC2 runner
id: start-ec2-runner
uses: machulav/ec2-github-runner@v2
with:
mode: start
github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}
ec2-image-id: ami-0a2d3c18efb0a2eb0
ec2-instance-type: m5.large
subnet-id: subnet-0463cb19720d02c7d
security-group-id: sg-068a1780a03660482
build:
name: Build
needs: start-ec2-runner # wait for the step to start the EC2 instance
runs-on: ${{ needs.start-ec2-runner.outputs.label }} # refers to the label used to register the runner
steps:
- name: Build
run: ./build.sh
stop-ec2-runner:
name: Stop EC2 runner
needs:
- start-ec2-runner # access outputs
- build # wait for the build job to finish
runs-on: ubuntu-latest
if: ${{ always() }} # always stop the EC2 runner, even if the previous job failed
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-1
- name: Stop EC2 runner
uses: machulav/ec2-github-runner@v2
with:
mode: stop
github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}
label: ${{ needs.start-ec2-runner.outputs.label }}
ec2-instance-id: ${{ needs.start-ec2-runner.outputs.ec2-instance-id }}
The solution requires you to add the following secrets to the GitHub repository.
- Static AWS credentials (IAM user):
AWS_ACCESS_KEY_ID
andAWS_SECRET_ACCESS_KEY
- Personal access token with access to
repo
scope:GH_PERSONAL_ACCESS_TOKEN
Pros
- Simple and easy-to-understand solution.
- Scalable as it launches an EC2 for every workflow/job.
- Free as in beer. (MIT License)
Cons
- Does not come with a ready to use AMI. Requires an AMI with Docker pre-installed or the use of
pre-runner-script
to install Docker on every launch. - Manual setup required: security group, VPC + subnet, GitHub personal access token, …
- Requires static credentials (IAM user) which AWS does not recommend.
- Uses GitHub-hosted runners to start and stop EC2 instance.
terraform-aws-github-runner: Terraform module to deploy self-hosted runner on AWS
Philips maintains a lively open-source project with terraform-aws-github-runner. As the name implies, the Terraform module provides self-hosted and scalable runners for GitHub Actions.
The architecture consists of the following building blocks:
- API Gateway
- Lambda
- SQS
- Event Bridge
- Auto Scaling Group
- EC2
- VPC
Overall, the architecture (see diagram) is quite complex.
Here is a summary on how to get started with terraform-aws-github-runner
.
- Set up a private GitHub app.
- Download or build code for Lambda.
- Setup Terraform module.
module "github-runner" {
source = "philips-labs/github-runner/aws"
version = "v5.17.3"
aws_region = "eu-west-1"
vpc_id = "vpc-001efbd83d4f4d8fd"
subnet_ids = ["subnet-0463cb19720d02c7d", "subnet-0f6208cd58b6452b8"]
prefix = "ghr"
github_app = {
key_base64 = "..."
id = "1"
webhook_secret = "..."
}
webhook_lambda_zip = "lambdas-download/webhook.zip"
runner_binaries_syncer_lambda_zip = "lambdas-download/runner-binaries-syncer.zip"
runners_lambda_zip = "lambdas-download/runners.zip"
enable_organization_runners = true
}
- Configure GitHub webhook.
- Install the GitHub app.
The terraform-aws-github-runner
solution supports re-using runners for multiple jobs as well as ephemeral runners. Optionally, an auto-scaling group can be used to provide a pool of runners to reduce latency when starting a job.
Pros
- Active and well-maintained open-source project.
- Optional pool with pre-warmed runners to reduce latency for starting a job.
Cons
- Complicated installation process which requires to consult the documentation a lot.
- Complex architecture and Terraform code, requires advanced Terraform and AWS skills.
HyperEnv: Deploy self-hosted GitHub runners on AWS with ease
Deploy self-hosted GitHub runners on AWS with ease by using HyperEnv in three simple steps by clicking through Amazon’s and GitHub’s web interface.
- Subscribe to HyperEnv via AWS Marketplace
- Create a CloudFormation stack to deploy HyperEnv
- Create a private GitHub app for your GitHub organization
HyperEnv runs 100% in your AWS account.
Here is how HyperEnv works after the installation:
- GitHub jobs starts and waits for runner.
- GitHub sends webhook event to HyperEnv.
- HyperEnv launches an EC2 instance which automatically starts and registers a GitHub runner.
- GitHub runner executes job.
- EC2 instance terminates.
HyperEnv provides an AMI which comes with the same tools pre-installed as GitHub-hosted runners (ubuntu-latest
).
Pros
- Easy to install: from start to finish in 15 minutes.
- Drop-in replacement for GitHub-hosted runners (compatible with
ubuntu-latest
). - Support by AWS and GitHub experts helping you to get started and solve problems.
Cons
- Costs $0.002 per vCPU and build minute on top of consumed AWS infrastructure resources (see cost calculator).