AWS EC2 Runner Investigation

This document explores the feasibility and trade-offs of migrating from the current mixed self-hosted runner setup to AWS EC2-based runners.

Current State

Runner Configuration

Runner TypePlatformUse CaseAvailability
Self-hosted WindowsWindows 11Android builds, GradleDeveloper machine
Self-hosted macOSmacOS SonomaiOS builds, XcodeDeveloper machine
GitHub-hostedubuntu-latestFallback, simple tasksAlways available

Current Pain Points

  1. Mixed Platform Complexity

    • Different shell syntaxes (PowerShell vs Bash)
    • Different path separators and encodings
    • Workflow files need platform-specific conditionals
  2. Availability Concerns

    • Self-hosted runners depend on developer machines being online
    • Builds fail silently when runners are offline
    • No build capability during travel or machine maintenance
  3. Cost Structure

    • GitHub-hosted macOS runners: $0.08/minute (8x Linux pricing)
    • Self-hosted: “Free” but ties up developer hardware
    • Hidden cost: Developer productivity impact
  4. Maintenance Burden

    • Keeping Xcode, Android SDK, JDK versions in sync
    • Runner software updates
    • Disk space management

AWS EC2 Options

Linux Runners (Android/Gradle)

Instance Types:

InstancevCPUMemoryCost/hr (On-Demand)Cost/hr (Spot)
c6i.xlarge48 GB$0.17~$0.05
c6i.2xlarge816 GB$0.34~$0.10
c7i.2xlarge816 GB$0.36~$0.11

Recommendation: c6i.2xlarge for faster Gradle builds

Estimated Monthly Cost:

  • Assuming 100 builds/month × 10 min avg = 17 hours
  • On-Demand: ~$6/month
  • Spot: ~$2/month

macOS Runners (iOS/Xcode)

Instance Types:

InstancevCPUMemoryCost/hrMin Allocation
mac2.metal1232 GB$1.08324 hours
mac2-m2.metal824 GB$0.6524 hours
mac2-m2pro.metal1232 GB$0.7724 hours

Critical Constraint: AWS requires 24-hour minimum allocation for Mac instances.

Estimated Monthly Cost:

  • Minimum: 468/month (mac2-m2.metal)
  • Typical: 554/month (mac2-m2pro.metal)

Cost Comparison

ScenarioCurrent CostEC2 CostSavings
Android only (Linux)~$0 (self-hosted)~$6/month-$6
iOS only (macOS)~$0 (self-hosted)~$500/month-$500
Full migration~$0~$506/month-$506
Hybrid (EC2 Linux + self-hosted macOS)~$0~$6/month-$6

Architecture Options

Option 1: Full EC2 Migration

┌─────────────────────────────────────────────────────────┐
│                    GitHub Actions                        │
└─────────────────────────┬───────────────────────────────┘
                          │
         ┌────────────────┼────────────────┐
         ▼                ▼                ▼
┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│ EC2 Linux   │  │ EC2 Linux   │  │ EC2 macOS   │
│ (Android)   │  │ (Gradle)    │  │ (iOS)       │
└─────────────┘  └─────────────┘  └─────────────┘

Pros:

  • 24/7 availability
  • Consistent environment
  • No developer machine dependency

Cons:

  • ~$500+/month for macOS
  • AWS account management overhead
  • Network latency for large artifacts

Option 2: Hybrid (EC2 Linux + Self-Hosted macOS)

┌─────────────────────────────────────────────────────────┐
│                    GitHub Actions                        │
└─────────────────────────┬───────────────────────────────┘
                          │
         ┌────────────────┼────────────────┐
         ▼                ▼                ▼
┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│ EC2 Linux   │  │ EC2 Linux   │  │ Self-Hosted │
│ (Android)   │  │ (Gradle)    │  │ macOS (iOS) │
└─────────────┘  └─────────────┘  └─────────────┘

Pros:

  • Low cost (~$6/month)
  • Eliminates Windows complexity
  • macOS still available when developer is active

Cons:

  • iOS builds still depend on availability
  • Mixed architecture remains (EC2 + self-hosted)

Option 3: Linux-Only with Cross-Compilation

┌─────────────────────────────────────────────────────────┐
│                    GitHub Actions                        │
└─────────────────────────┬───────────────────────────────┘
                          │
                          ▼
              ┌─────────────────────┐
              │     EC2 Linux       │
              │  (Android + KMP)    │
              └─────────────────────┘
                          │
                          ▼
              ┌─────────────────────┐
              │  Manual iOS Builds  │
              │  (Xcode Cloud/Local)│
              └─────────────────────┘

Pros:

  • Lowest cost (~$6/month)
  • Simplest infrastructure
  • Linux-only = consistent shell/encoding

Cons:

  • No automated iOS builds
  • KMP iOS artifacts require manual verification
  • Breaks iOS CI/CD pipeline

Option 4: GitHub-Hosted Only

┌─────────────────────────────────────────────────────────┐
│                    GitHub Actions                        │
└─────────────────────────┬───────────────────────────────┘
                          │
         ┌────────────────┼────────────────┐
         ▼                ▼                ▼
┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│ ubuntu-     │  │ ubuntu-     │  │ macos-      │
│ latest      │  │ latest      │  │ latest      │
└─────────────┘  └─────────────┘  └─────────────┘

Estimated Cost:

  • Linux: 8/month
  • macOS: 40/month
  • Total: ~$48/month

Pros:

  • Zero infrastructure management
  • Always available
  • Pay-per-use pricing

Cons:

  • macOS costs add up with frequent builds
  • Less control over environment
  • Slower cold-start times

Recommendation

Short Term: Option 2 (Hybrid)

  1. Migrate Android/Gradle to EC2 Linux

    • Eliminates Windows runner complexity
    • Consistent Linux environment
    • ~$6/month cost
  2. Keep Self-Hosted macOS for iOS

    • Avoid $500+/month macOS EC2 cost
    • Accept availability limitations
    • Use GitHub-hosted macos-latest as fallback for critical builds

Long Term: Re-evaluate

  • If iOS build frequency increases: Consider Xcode Cloud or dedicated EC2 mac
  • If costs are acceptable: Full GitHub-hosted for simplicity
  • If team grows: EC2 mac becomes more cost-effective per-developer

Implementation Plan

Phase 1: EC2 Linux Setup

  1. Create EC2 instance (c6i.2xlarge)
  2. Install GitHub Actions runner
  3. Configure Android SDK, JDK, Gradle
  4. Test with Android build workflow
  5. Migrate Android CI to EC2 runner

Phase 2: Workflow Simplification

  1. Remove Windows-specific conditionals
  2. Standardize on Bash scripts
  3. Update runner selection logic
  4. Remove PowerShell workarounds

Phase 3: Monitoring & Optimization

  1. Track build times and costs
  2. Implement Spot instance failover
  3. Consider auto-scaling based on queue depth
  4. Evaluate cold-start vs always-on trade-offs

Cost Projection

MonthEC2 LinuxSelf-Hosted macOSGitHub-Hosted FallbackTotal
1$10 (setup)$0$5$15
2-12$6/month$0$2/month$8/month
Year 1$76$0$27$103

Compare to full GitHub-hosted: ~$576/year

Savings: ~$473/year while improving reliability for Android builds.

Open Questions

  1. Spot Instance Reliability: How often do Spot instances get interrupted during builds?
  2. Runner Registration: Should we use ephemeral runners or persistent registration?
  3. Artifact Caching: Can we use S3 for Gradle/CocoaPods cache?
  4. Security: VPC configuration for GitHub Actions connectivity?