Module:
sourcefuse/arc-github-runner/aws
Registry: https://registry.terraform.io/modules/sourcefuse/arc-github-runner/aws
Category: DevOps / CI/CD
Source: https://github.com/sourcefuse/terraform-aws-arc-github-runner
Tip
🤖 New: Use this module with AI assistants via the ARC IaC MCP Server — search, scaffold, and security-scan ARC modules from natural language. Quick setup ↓
Deploys a self-hosted GitHub Actions runner on an EC2 instance with auto-registration, SSM access, and configurable labels.
- EC2-based self-hosted GitHub Actions runner
- Automatic runner registration with GitHub token
- Configurable runner labels for job targeting
- SSM Session Manager access (no SSH required)
- IAM instance profile with configurable policies
- VPC and security group configuration
This module utilizes different local-exec provisioners to execute scripts for obtaining the needed GitHub Runner token
and remove the runner from the organization when the resources are destroyed.
See Pre-Requisites for information on the needed permissions these scripts will require.
Set eks_runner_config.create = true to run autoscaling, ephemeral runners on an existing EKS cluster. Set
create_ec2_runner = false if you do not also want the EC2 runner. The root module then deploys the official Actions Runner Controller runner scale sets with Helm, through
the modules/eks-runner submodule. It supports multiple scale sets, Pod Identity or IRSA, and
GitHub App auth. See example/eks-runner.
module "github_runner" {
source = "sourcefuse/arc-github-runner/aws"
# version = "x.y.z"
namespace = "arc"
environment = "dev"
region = "us-east-1"
create_ec2_runner = false
github_token = data.aws_ssm_parameter.github_token.value # or github_app_private_key
eks_runner_config = {
create = true
cluster_name = "my-eks-cluster"
github_config_url = "https://github.com/my-org"
github_auth_method = "pat"
runner_scale_sets = {
default = { min_runners = 1, max_runners = 10 }
}
}
}The calling configuration must configure the helm and kubernetes providers for the cluster. EC2-only inputs
(vpc_id, subnet_id, ...) are not needed in this mode.
You will need to have a GitHub Personal Access Token (PAT) with admin:org permissions in order to manage GitHub runners for the Organization.
If you do not have sufficient permissions to GitHub, the runner will not register.
Once you've obtained a PAT, you will need to set it so Terraform can access it.
The recommended approach to this is to save it in Systems Manager Parameter Store with the Parameter name of: /<namespace>/<environment>/github/token
You can reference this parameter via a data lookup:
data "aws_ssm_parameter" "github_token" {
name = "/${var.namespace}/${var.environment}/github/token"
}To see a full EC2 example, check out the EC2 runner example.
For EKS runner scale sets, see the EKS runner example.
module "runner" {
source = "sourcefuse/arc-github-runner/aws"
version = "0.2.6"
namespace = var.namespace
environment = var.environment
region = var.region
subnet_id = local.private_subnet_ids[0]
vpc_id = data.aws_vpc.this.id
instance_type = "t2.micro"
github_token = data.aws_ssm_parameter.github_token.value
runner_labels = "example,${var.namespace},${var.environment}"
tags = module.tags.tags
}| Name | Type | Description |
|---|---|---|
namespace |
string |
Namespace prefix |
environment |
string |
Deployment environment |
subnet_id |
string |
Subnet ID for the runner EC2 instance |
vpc_id |
string |
VPC ID |
github_token |
string |
GitHub PAT or registration token |
runner_labels |
string |
Comma-separated runner labels |
| Name | Description |
|---|---|
instance_id |
EC2 instance ID of the runner |
instance_private_ip |
Private IP of the runner |
The complete inputs/outputs reference is auto-generated below.
| Name | Version |
|---|---|
| terraform | >= 1.5.0, < 2.0.0 |
| aws | >= 5.40, < 6.0 |
| helm | >= 2.12, < 4.0 |
| kubernetes | >= 2.20, < 4.0 |
| null | >= 3.0 |
| Name | Version |
|---|---|
| aws | 5.100.0 |
| null | 3.3.2 |
| Name | Source | Version |
|---|---|---|
| eks_runner | ./modules/eks-runner | n/a |
| runner | sourcefuse/arc-ec2/aws | 0.0.5 |
| Name | Type |
|---|---|
| aws_ssm_association.dependencies | resource |
| aws_ssm_association.runner_install | resource |
| aws_ssm_document.dependencies | resource |
| aws_ssm_document.runner_install | resource |
| null_resource.cleanup | resource |
| null_resource.prepare | resource |
| aws_caller_identity.this | data source |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| ami | AMI information for the EC2 instance | object({ |
{ |
no |
| associate_public_ip_address | Associate a public IP address with the instance | bool |
false |
no |
| create_ec2_runner | Whether to create the EC2 (SSM managed) runner. Set to false when only EKS runners are needed (eks_runner_config.create = true). | bool |
true |
no |
| ec2_runner_iam_role_policy_arns | IAM role policies to attach to the Runner instance | list(string) |
[ |
no |
| eks_runner_config | EKS runner configuration. Set create = true to deploy autoscaling, ephemeralrunner scale sets on an existing EKS cluster (official Actions Runner Controller charts). Attributes map 1:1 to the inputs of modules/eks-runner, where defaults, validation andfull descriptions live. Unset attributes use the submodule defaults. Required when create = true: cluster_name, github_config_url. Credentials are passed separately as sensitive inputs: github_token (PAT)or github_app_private_key (GitHub App).Example: eks_runner_config = { create = true cluster_name = "my-eks-cluster" github_config_url = "https://github.com/my-org" github_auth_method = "pat" runner_scale_sets = { default = { min_runners = 1, max_runners = 10 } } } |
object({ |
{ |
no |
| environment | Name of the environment, i.e. dev, stage, prod | string |
n/a | yes |
| github_app_private_key | GitHub App private key (PEM). Used by the EKS runner when eks_runner_config.github_auth_method is "github_app". | string |
null |
no |
| github_owner | GitHub Owner the runner belongs to. If you are adding a repo, the format will be owner/repo |
string |
"sourcefuse" |
no |
| github_token | GitHub Personal Access Token. - EC2 runner (create_ec2_runner): required, with admin:org scope. Used to obtain a runner registration token, seeCreate a registration token for an organization. - EKS runner (eks_runner_config.create): used when eks_runner_config.github_auth_method is "pat". |
string |
null |
no |
| instance_type | The instance type for the EC2 instance. Default is t3a.medium. | string |
"t3a.medium" |
no |
| monitoring_enabled | Launched EC2 instance will have detailed monitoring enabled | bool |
true |
no |
| namespace | Namespace of the project, i.e. refarch | string |
n/a | yes |
| region | AWS region | string |
n/a | yes |
| repos_or_orgs | Whether the API will register / deregister the runner in repos or orgs. Options are orgs and repos |
string |
"orgs" |
no |
| root_block_device_encrypted | Whether to encrypt the root block device | bool |
true |
no |
| root_block_device_kms_key_id | KMS key ID used to encrypt EBS volume. When specifying root_block_device_kms_key_id, root_block_device_encrypted needs to be set to true | string |
null |
no |
| root_volume_size | Size of the root volume in gigabytes | string |
"80" |
no |
| root_volume_type | Type of root volume. Can be standard, gp2, gp3, io1 or io2 | string |
"gp2" |
no |
| runner_labels | Labels to assign the GitHub Runner. If no values are given, the default labels will be: - self-hosted- Base OS, i.e. Linux- Architecture, i.e. X64These labels cannot be overridden. Separate labels via comma, i.e. dev,docker,another_label |
string |
"" |
no |
| runner_name | Name to assign the GitHub Runner. If no value is given, it will use the ec2 instance name. | string |
null |
no |
| runner_user | OS user that owns and runs the runner systemd service. Created if it does not exist. | string |
"ubuntu" |
no |
| runner_version | Version of the official GitHub Actions runner (github.com/actions/runner) to install on the host. Pin at or above GitHub's current minimum so the runner is never forced into a self-update. See the releases page for the latest tag. |
string |
"2.336.0" |
no |
| subnet_id | Subnet ID for the EC2 instance to be assigned to. Required when create_ec2_runner is true. | string |
null |
no |
| tags | Default tags to apply to every resource | map(string) |
{} |
no |
| vpc_id | VPC ID for EC2 instance to reside in. Required when create_ec2_runner is true. | string |
null |
no |
| Name | Description |
|---|---|
| ec2_runner_instance_id | Instance ID of the EC2 Runner |
| ec2_runner_instance_name | Instance Name of the EC2 Runner |
| ec2_runner_role | Instance role name (created by arc-ec2 as -role) |
| ec2_runner_role_arn | Instance role ARN |
| eks_controller_namespace | Kubernetes namespace of the Actions Runner Controller. |
| eks_ebs_csi_role_arn | IAM role ARN of the EBS CSI driver (null if not installed). |
| eks_github_config_secret_name | Kubernetes secret holding the GitHub credentials of the EKS runners. |
| eks_runner_namespace | Kubernetes namespace of the EKS runner scale sets. |
| eks_runner_scale_sets | Deployed EKS runner scale sets: name (use in runs-on:), Helm release, runner service account and IAM role ARN. |
| eks_storage_class_name | StorageClass created for runner work volumes (null if not created). |
- Configure pre-commit hooks
pre-commit install
while Contributing or doing git commit please specify the breaking change in your commit message whether its major,minor or patch
For Example
git commit -m "your commit message #major"By specifying this , it will bump the version and if you dont specify this in your commit message then by default it will consider patch and will bump that accordingly
- Tests are available in
testdirectory - Configure the dependencies
cd test/ go mod init github.com/sourcefuse/terraform-aws-refarch-github-runner go get github.com/gruntwork-io/terratest/modules/terraform - Now execute the test
go test -timeout 30m
The ARC IaC MCP Server is a hosted Model Context Protocol service that lets AI assistants browse, search, scaffold, compare, and security-scan any of the SourceFuse ARC Terraform modules — directly from natural language.
What you can do with it:
- Discover — search and filter modules by keyword or AWS resource type.
- Understand — get inputs, outputs, and resources for any module without leaving your editor.
- Scaffold — generate production-ready, multi-file Terraform with cross-module wiring already done.
- Secure — scan generated or existing HCL for misconfigurations before it hits a PR.
- Compare — diff modules side-by-side to make informed architectural decisions.
The MCP endpoint is https://arc-iac-mcp.sourcef.us/mcp. Pick your client:
Claude Code CLI:
claude mcp add arc-iac --transport http https://arc-iac-mcp.sourcef.us/mcpClaude Desktop — edit ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"arc-iac": {
"url": "https://arc-iac-mcp.sourcef.us/mcp"
}
}
}Cursor / Windsurf / Kiro — add the same block to .cursor/mcp.json (or the equivalent for your client).
- "List all ARC modules sorted by downloads"
- "What inputs does
arc-ecsrequire?" - "Scaffold a production-ready
arc-dbAurora setup with Secrets Manager" - "Compare
arc-eksandarc-ecsfor running 10 microservices" - "Scan this Terraform before I raise a PR:
<paste HCL>"
See the ARC IaC MCP repo for the full tool reference, troubleshooting tips, and local-development instructions.
See CONTRIBUTING.md for commit conventions and development setup.
This project is authored by:
- SourceFuse ARC Team