quickstart →

Flex installation guide

RunsOn is the best way to run GitHub Actions in your own AWS infrastructure, and get 10x cheaper runners.

What changes in your workflows#

Once the stack is installed, you change one line per job. You swap the GitHub-hosted label for a RunsOn label:

.github/workflows/ci.yml
runs-on: ubuntu-latest
runs-on: runs-on=${{ github.run_id }}/runner=2cpu-linux-x64

The label describes the runner, so each job can ask for a different one. The stack doesn’t need a config change or a redeploy:

.github/workflows/ci.yml
jobs:
lint:
runs-on: runs-on=${{ github.run_id }}/runner=2cpu-linux-x64
test:
runs-on: runs-on=${{ github.run_id }}/runner=16cpu-linux-x64/extras=s3-cache
build-arm64:
runs-on: runs-on=${{ github.run_id }}/cpu=8/family=c8g/image=ubuntu24-full-arm64/volume=200gb

Each job gets its own ephemeral EC2 instance in your AWS account, which terminates when the job ends. See all job labels, or Flex vs Fleet if a platform team should own runner shapes instead.

Before you start#

The entire RunsOn stack can be installed in 10 minutes in your AWS account and requires:

  • a license key (free for non-commercial use, or 15 days trial available).
  • an AWS account: we recommend that you set up RunsOn in its own dedicated AWS sub-account, to further improve isolation of your workflows.

If at any point you are stuck, please reach out to me at ops@runs-on.com or book an onboarding call ↗.

CloudFormation#

1. Select your AWS region#

To get started, simply select one of the regions below. This will redirect you to the CloudFormation interface:

Or, if you prefer creating the stack manually with CloudFormation, you can use the following template URL:

https://runs-on.s3.eu-west-1.amazonaws.com/cloudformation/template-v3.4.0.yaml

2. Create the stack#

After you click on one of the regions above, you will end up on a screen with a few inputs fields:

Inputs for RunsOn stack

You must fill the fields under Main configuration [required]:

  • the name of your GitHub organization or personal account where you want to install RunsOn (e.g. my-org).
  • the license key for RunsOn, either as a plain text value or a reference to an SSM parameter. You can get one here, with a 15-day free trial.
  • an email address where cost & alert reports will be sent.
  • optionally, the RunsOn Environment name if you intentionally operate multiple environments.

Finally, acknowledge the CloudFormation capabilities and transforms, then continue to the review screen. Note that the stack will create a dedicated IAM role for the RunsOn service, with the most restricted set of permissions required.

Create RunsOn stack

On the final review screen, click “Submit” to start creating the stack.

Submit RunsOn stack creation

Once the stack creation is complete, the HTTPS URL to your RunsOn instance will be displayed in the CloudFormation stack Outputs, under the RunsOnEntryPoint output parameter:

CloudFormation Output

During the stack creation, you will receive an email to confirm your subscription to the cost & alert SNS topic. Confirm it: in v3 this email is how cost reports and alerts reach you.

Confirm SNS notification
If this step goes wrong 1 known issue

Stack creation fails on RunsOnWorkerCluster with Unable to assume the service linked role. Please verify that the ECS service linked role exists. Create the ECS service-linked role once in the target AWS account, then retry the stack creation:

aws iam create-service-linked-role --aws-service-name ecs.amazonaws.com

3. Register the GitHub app#

To finish the installation, from the CloudFormation stack Outputs, simply click on the HTTPS URL for the RunsOn entrypoint, and click “Register app”:

Register GitHub App

You will then be directed to a screen where you can adjust your app name:

Create GitHub App

And then select the repositories you want this app to be installed on:

Set permissions for GitHub App

After you confirm, you will get redirected to the RunsOn service, which should display the following success screen:

Success
If this step goes wrong 1 known issue

GitHub shows a 500 Server Error after “Register app”. Log into GitHub in this browser and try again: GitHub returns a generic 500 on the app manifest page (github.com/settings/apps/manifest) when you are not signed in.

4. Update your workflows#

It’s now time to update your workflows to select one of the RunsOn runner types! For instance:

.github/workflows/ci.yml
runs-on: ubuntu-latest
runs-on: runs-on=${{ github.run_id }}/runner=2cpu-linux-x64
If this step goes wrong 1 known issue

Jobs stay queued and no runner appears. Allow repository-level self-hosted runners in your GitHub organization’s General Actions settings: https://github.com/organizations/<YOUR_ORG>/settings/actions.

Allow repository-level runners in organization settings

Terraform / OpenTofu#

RunsOn provides an official Terraform module for deploying and managing your RunsOn infrastructure as code.

For v3, Terraform / OpenTofu is also the recommended path whenever you need capabilities that are no longer exposed by the built-in CloudFormation template, such as GHES support, reusing an existing VPC, or IAM permission boundaries.

Official Terraform module#

The module is available on both registries:

The recommended v3 approach is to use the explicit Flex submodule:

main.tf
module "runs_on_flex" {
source = "runs-on/runs-on/aws//modules/flex"
version = "v3.4.0"
github_organization = "my-org"
license_key = "your-license-key"
email = "alerts@example.com"
app_size = "small"
app_budget_daily_usd = 10
vpc_id = "vpc-xxxxxxxx"
public_subnet_ids = ["subnet-pub1", "subnet-pub2"]
private_subnet_ids = ["subnet-priv1", "subnet-priv2"]
}
output "runs_on_ingress_url" {
description = "RunsOn setup and webhook ingress URL"
value = module.runs_on_flex.ingress.url
}
output "runs_on_getting_started" {
description = "RunsOn post-apply setup instructions"
value = module.runs_on_flex.stack.getting_started
}

Every input is listed in Flex Terraform inputs. For examples, see the official module on GitHub ↗.

The Terraform module should be used in the following cases:

  • Your organization already uses Terraform to manage AWS infrastructure, and you want to use the same tool to manage your RunsOn stack.
  • You want full control over how the networking stack is configured, and/or want to reuse an existing VPC.
  • You need GHES support or IAM permission boundaries.

Resources#