Skip to main content

Self-Hosted Runners

Self-hosted GitHub Actions runners on EC2 via runs-on.com for jobs requiring private network access (database migrations, Terraform) through Transit Gateway.

Problems this Architecture solves

  • Enables CI/CD jobs that must reach private infrastructure and internal services not accessible from hosted runners.
  • Avoids keeping long-lived build workers running all the time by scaling runners up only when jobs exist.
  • Centralizes caching, logging, and operational visibility for privileged automation workloads.

Key Features

  • Private Network Access: Runners in VPC can access RDS, ElastiCache via Transit Gateway
  • Auto-Scaling: Spin up runners on-demand, terminate when idle
  • Cost Optimization: Only pay for runners when jobs are running
  • S3 Caching: Cache dependencies and build artifacts
  • CloudWatch Logs: Centralized logging for all runner activity
  • Spot Instances: Use spot instances for cost savings

Use Cases

Database Migrations

  • Connect to RDS in private subnets
  • Run migrations via Flyway or Liquibase
  • No public internet exposure

Terraform Deployments

  • Access AWS APIs via VPC endpoints
  • Deploy infrastructure changes
  • State stored in S3 with DynamoDB locking

Integration Tests

  • Test against real databases and services
  • Access internal APIs
  • Run E2E tests in isolated environment

RunsOn Configuration

Instance Types

  • t3.medium: General-purpose jobs (2 vCPU, 4 GB)
  • c6i.xlarge: CPU-intensive builds (4 vCPU, 8 GB)
  • r6i.large: Memory-intensive tests (2 vCPU, 16 GB)

Auto-Scaling

  • Min: 0 runners (scale to zero when idle)
  • Max: 20 runners (burst capacity)
  • Scale-up: 30 seconds to provision new runner
  • Scale-down: 5 minutes idle timeout

GitHub Actions Workflow

jobs:
deploy:
runs-on: runs-on,runner=2cpu-linux-x64
steps:
- uses: actions/checkout@v4
- name: Run Terraform
run: terraform apply -auto-approve