Skip to content

Deploy GitHub Action runners in your AWS Account. Uses AWS CodeBuild to manage ephemeral runners, so you don't have to.

License

Notifications You must be signed in to change notification settings

cloudandthings/terraform-aws-github-runners

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

terraform-aws-github-runners

Deploy GitHub Action runners in your AWS Account. Uses AWS CodeBuild to manage ephemeral runners, so you don't have to.

GitHub repo link


Maintenance Terraform Version pre-commit

Why?

Deploying self-hosted GitHub runners should be simple and cheap. It shouldn't need a long setup process or a lot of infrastructure.

Features

  • Simple. See the examples for a quick-start.
  • Serverless. No EC2 instances that need to be maintained.
  • Cost-effective. You are billed only when a CodeBuild project is running your GitHub workflow. Projects are billed per build minute.
  • Scalable. Runners are subject to AWS CodeBuild quotas

For many projects, CI/CD is run infrequently and there are long periods of time when no CI/CD runs occur. Using AWS CodeBuild means that GitHub runners are always available, billed only when used, and cost nothing when idle.

This module additionally does not require public inbound traffic, and it can be easily customised if needed.

Previous version notice

Previously, this module used EC2 spot instances with configurable AutoScaling.

Should you wish to continue to use this older approach, the code has been moved to terraform-aws-github-runners-ec2

Known limitations

  1. Additional config needed if using custom ECR image

If a custom ECR image is used then additional install and config is needed when building the Docker image. This is because some of the GitHub uses actions do not work by default.

How it works

An AWS CodeBuild Project and a webhook is created in a specific GitHub repo. The webhook is used to trigger the build project when a Github Action is triggered. The CodeBuild project run will self-configure as a GitHub runner, and run the job commands in the repo's workflow file.

Steps execute arbitrary commands, defined by your repo workflows.

For example:

  • Perform a linting check.
  • Connect to another AWS Account using an IAM credential and operate on some AWS infrastructure.
  • Anything else...

How to use it

1. Setup authentication to GitHub

There are several ways to set up authentication to GitHub. Follow the guide here.

2. Configure this module

Configure and deploy this module using Terraform. See examples below.

3. (Optional) Use a custom Docker image

You may want the runner to execute in a pre-configured environment.

The value of environment_image is used to specify a Docker image for this purpose.

Valid values include:

  • Docker images provided by CodeBuild, e.g aws/codebuild/amazonlinux2-x86_64-standard:4.0
  • Docker Hub images, e.g. hashicorp/terraform:latest
  • Full Docker repository URIs, such as those for Amazon ECR, e.g. 137112412989.dkr.ecr.us-west-2.amazonaws.com/amazonlinux:latest

Logic in the module is used to determine the final image to be used.

  • Whenever you specify a value for var.environment_image then your specified value is used.
  • If no value was specified for var.environment_image and you are not using Amazon ECR, then a default CodeBuild image is used - specifically aws/codebuild/amazonlinux2-x86_64-standard:5.0.
  • If no value was specified for var.environment_image and you are using Amazon ECR, then an image with a latest tag is assumed to exist in your Amazon ECR repo and the module will try to use it.

To use Amazon ECR you may either provide the name of an existing ECR repository, or use this module to create one for you. You will need to ensure an image is created in the ECR repository with a latest tag, or you can specify a different tag by using a specific value for environment_image as described above.

The final value of environment_image is provided as an output variable so you can view and use it.

More info

Module Docs

Basic Example

module "github_runner" {
  source = "../../"

  # Required parameters
  ############################
  # Naming for all created resources
  name            = "github-runner-codebuild-test"
  source_location = "https://github.com/my-org/my-repo.git"

  # Environment image is not specified so it will default to:
  # "aws/codebuild/amazonlinux2-x86_64-standard:5.0"

  # Optional parameters
  ############################
  github_personal_access_token = "example"

  vpc_id     = "vpc-0ffaabbcc1122"
  subnet_ids = ["subnet-0123", "subnet-0456"]
}

Advanced Example

locals {
  naming_prefix = "test-github-runner"
  vpc_id        = "vpc-0ffaabbcc1122"
}

# Create a custom security-group to allow SSH to all EC2 instances
resource "aws_security_group" "this" {
  name        = "${local.naming_prefix}-sg"
  description = "GitHub runner ${local.naming_prefix}-sg"

  # tfsec:ignore:aws-ec2-no-public-egress-sgr
  egress {
    description = "egress"
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  vpc_id = local.vpc_id
  #checkov:skip=CKV2_AWS_5:The SG is attached by the module.
  #checkov:skip=CKV_AWS_382:Egress to GitHub Actions is required for the runner to work.
}

data "http" "myip" {
  url = "http://ipv4.icanhazip.com"
}

resource "aws_security_group_rule" "ssh_ingress" {
  description       = "Allow SSH ingress to EC2 instance"
  type              = "ingress"
  from_port         = 22
  to_port           = 22
  protocol          = "tcp"
  cidr_blocks       = ["${chomp(data.http.myip.body)}/32"]
  security_group_id = aws_security_group.this.id
}

module "github_runner" {
  source = "../../"

  # Required parameters
  ############################
  source_location                            = "https://github.com/my-org/my-repo.git"
  github_personal_access_token_ssm_parameter = "example"

  # Naming for all created resources
  name = "github-runner-codebuild-test"

  # Environment image is not specified so it will default to:
  # "${local.aws_account_id}.dkr.ecr.${local.aws_region}.amazonaws.com/${local.ecr_repository_name}:latest"
  # Because an ECR repo is used

  vpc_id     = "vpc-0ffaabbcc1122"
  subnet_ids = ["subnet-0123", "subnet-0456"]

  # Optional parameters
  ################################
  create_ecr_repository = true

  security_group_ids         = [aws_security_group.this.id]
  cloudwatch_logs_group_name = "/some/log/group"
}

Inputs

Name Description Type Default Required
build_timeout Number of minutes, from 5 to 2160 (36 hours), for AWS CodeBuild to wait until timing out any related build that does not get marked as completed. number 5 no
cloudwatch_log_group_retention_in_days Number of days to retain log events number 14 no
cloudwatch_logs_group_name Name of the log group used by the CodeBuild project. If not specified then a default is used. string null no
cloudwatch_logs_stream_name Name of the log stream used by the CodeBuild project. If not specified then a default is used. string null no
create_cloudwatch_log_group Determines whether a log group is created by this module. If not, AWS will automatically create one if logging is enabled bool true no
create_ecr_repository If set to true then an ECR repository will be created, and an image needs to be pushed to it before running the build project string false no
description Short description of the project. string null no
ecr_repository_name Name of the ECR repository to create or use. If not specified and create_ecr_repository is true, then a default is used. string null no
environment_compute_type Information about the compute resources the build project will use. Valid values: BUILD_GENERAL1_SMALL, BUILD_GENERAL1_MEDIUM, BUILD_GENERAL1_LARGE, BUILD_GENERAL1_2XLARGE, BUILD_LAMBDA_1GB, BUILD_LAMBDA_2GB, BUILD_LAMBDA_4GB, BUILD_LAMBDA_8GB, BUILD_LAMBDA_10GB. BUILD_GENERAL1_SMALL is only valid if type is set to LINUX_CONTAINER. When type is set to LINUX_GPU_CONTAINER, compute_type must be BUILD_GENERAL1_LARGE. When type is set to LINUX_LAMBDA_CONTAINER or ARM_LAMBDA_CONTAINER, compute_type must be BUILD_LAMBDA_XGB string "BUILD_GENERAL1_SMALL" no
environment_image Docker image to use for this build project. Valid values include Docker images provided by CodeBuild (e.g aws/codebuild/amazonlinux2-x86_64-standard:4.0), Docker Hub images (e.g., hashicorp/terraform:latest) and full Docker repository URIs such as those for ECR (e.g., 137112412989.dkr.ecr.us-west-2.amazonaws.com/amazonlinux:latest). If not specified and not using ECR, then a default CodeBuild image is used, or if using ECR then an ECR image with a latest tag is used. string null no
environment_type Type of build environment to use for related builds. Valid values: LINUX_CONTAINER, LINUX_GPU_CONTAINER, WINDOWS_CONTAINER (deprecated), WINDOWS_SERVER_2019_CONTAINER, ARM_CONTAINER, LINUX_LAMBDA_CONTAINER, ARM_LAMBDA_CONTAINER string "LINUX_CONTAINER" no
github_personal_access_token The GitHub personal access token to use for accessing the repository. If not specified then GitHub auth must be configured separately. string null no
github_personal_access_token_ssm_parameter The GitHub personal access token to use for accessing the repository. If not specified then GitHub auth must be configured separately. string null no
iam_role_name Name of the IAM role to be used. If not specified then a role will be created string null no
iam_role_permissions_boundary ARN of the policy that is used to set the permissions boundary for the IAM service role string null no
iam_role_policies Map of IAM role policy ARNs to attach to the IAM role map(string) {} no
kms_key_id The AWS KMS key to be used string null no
name Created resources will be named with this. string n/a yes
s3_logs_bucket_name Name of the S3 bucket to store logs in. If not specified then logging to S3 will be disabled. string null no
s3_logs_bucket_prefix Prefix to use for the logs in the S3 bucket string "" no
security_group_ids The list of Security Group IDs for AWS CodeBuild to launch ephemeral EC2 instances in. list(string) [] no
security_group_name Name to use on created Security Group. Defaults to name string null no
source_location Your source code repo location, for example https://github.com/my/repo.git string n/a yes
subnet_ids The list of Subnet IDs for AWS CodeBuild to launch ephemeral EC2 instances in. list(string) [] no
vpc_id The VPC ID for AWS CodeBuild to launch ephemeral instances in. string null no

Modules

No modules.


Outputs

Name Description
aws_security_group_id ID of the security group created for the CodeBuild project
codebuild_project_arn ARN of the CodeBuild project, to be used when running GitHub Actions
codebuild_project_name Name of the CodeBuild project, to be used when running GitHub Actions
codebuild_role_name Name of the CodeBuild role, to be used when running GitHub Actions
ecr_repository_name Name of the ECR repository, to be used when to push custom docker images for the CodeBuild project
environment_image Docker image used for this CodeBuild project

Providers

Name Version
aws ~> 5

Requirements

Name Version
terraform >= 0.14.0
aws ~> 5
http ~> 3.0
null ~> 3.2

Resources

Name Type
aws_cloudwatch_log_group.codebuild resource
aws_codebuild_project.this resource
aws_codebuild_source_credential.ssm resource
aws_codebuild_source_credential.string resource
aws_codebuild_webhook.this resource
aws_ecr_lifecycle_policy.policy resource
aws_ecr_repository.this resource
aws_iam_role.this resource
aws_iam_role_policy.cloudwatch_required resource
aws_iam_role_policy.ecr_required resource
aws_iam_role_policy.networking_required resource
aws_iam_role_policy.s3_required resource
aws_iam_role_policy_attachment.additional resource
aws_security_group.codebuild resource
aws_vpc_security_group_egress_rule.codebuild resource
aws_vpc_security_group_ingress_rule.codebuild resource
aws_caller_identity.current data source
aws_cloudwatch_log_group.codebuild data source
aws_iam_policy_document.assume_role data source
aws_iam_policy_document.cloudwatch_required data source
aws_iam_policy_document.ecr_required data source
aws_iam_policy_document.networking_required data source
aws_iam_policy_document.s3_required data source
aws_region.current data source
aws_ssm_parameter.github_personal_access_token data source

<!-- END_TF_DOCS -->

About

Deploy GitHub Action runners in your AWS Account. Uses AWS CodeBuild to manage ephemeral runners, so you don't have to.

Resources

License

Stars

Watchers

Forks

Packages

No packages published