Terraform module to set up self-hosted GitHub Actions runners in AWS CodeBuild containers to process GitHub Actions workflow jobs.
This module is mainly based in Self-hosted GitHub Actions runners in AWS CodeBuild and has been configured to support a webhook at the organization level.
To use GitHub Actions self-hosted runners in CodeBuild, update your GitHub Actions workflow YAML file in GitHub.
Table of Contents:
A CodeBuild project is configured to set up self-hosted GitHub Actions runners in CodeBuild containers to process GitHub Actions workflow jobs. This is done by setting up a webhook using a CodeBuild project, and updating the GitHub Actions workflow YAML to use self-hosted runners hosted on CodeBuild machines.
The GitHub self-hosted runners will be created as an ephemeral runner in the repository that made the request event WORKFLOW_JOB_QUEUED
and the runs-on
setting in your GitHub workflow must set according the expected format by AWS CodeBuild, otherwise the request won't be processed.
The high-level steps to configure a CodeBuild project to run GitHub Actions jobs are as follows:
- Create a personal access token to connect the CodeBuild project to GitHub.
- Create a CodeBuild project with a webhook and set up the webhook with the
WORKFLOW_JOB_QUEUED
event filter. - Update your GitHub Actions workflow YAML in GitHub to configure your build environment.
-
By default CodeBuild logs are stored in AWS CloudWatch in the
/aws/codebuild/<code_project_name>
log group. To change this, set theinput_codebuild_logs_config
input variable. -
All resources with tags support, will be tagged with the following tags as default:
Terraform
: indicates the resources is managed by Terraform. Valuetrue
.TerraformWorkspace
: indicates the current Terraform's workspace. If no workspace is used, the value isdefault
.
Additional tags can be defined by setting the
tags
input variable, e.g.:tags = { Project = "MyProject" TerraformModule = "MyModule" }
When working with GitHub source CodeBuild webhooks, the CodeBuild service will automatically create (on aws_codebuild_webhook
resource creation) and delete (on aws_codebuild_webhook
resource deletion) the GitHub repository webhook using its granted OAuth permissions.
The AWS account that Terraform uses to create CodeBuild webhook must have authorized CodeBuild to access GitHub's OAuth API in each applicable region. This is a manual step that must be done before executing this Terraform module. If OAuth is not configured, AWS will return an error similar to ResourceNotFoundException: Could not find access token for server type github
.
OAuth can be configured by setting the default source credential for CodeBuild in the working region, e.g.: https://eu-west-1.console.aws.amazon.com/codesuite/codebuild/sourceCredentials/default?provider=github®ion=eu-west-1
. Three options are available:
- GitHub App: Connect project to GitHub using an AWS managed GitHub App.
- Personal access token: Connect project to GitHub using a personal access token.
- OAuth App: Connect project to GitHub using an OAuth App.
Create a fine-grained personal access token with the following permissions:
-
Repository permissions:
Contents
: Read-only. Grants access to private repositories.Commit statuses
: Read and write. Grants permission to create commit statuses.Webhooks
: Read and write. Grants permission to manage webhooks.Administration
: Read and write. Grants administration permissions on repositories.
-
Organization permission:
Webhooks
: Read and write. Grants permission to manage webhooks for an organization.
Then, save the token value in AWS Secrets Manager. The new secret must have the following keys and values (update the <GH_PAT>
placeholder with the PAT value):
Key | Value |
---|---|
ServerType |
GITHUB |
AuthType |
PERSONAL_ACCESS_TOKEN |
Token |
<GH_PAT> |
and the following tags:
Key | Value |
---|---|
codebuild:source |
|
codebuild:source:provider |
github |
codebuild:source:type |
personal_access_token |
Using AWS CLI (update the <GH_PAT>
placeholder with the PAT value):
export AWS_REGION="eu-west-1"
aws secretsmanager create-secret \
--region "$AWS_REGION"\
--name 'aws-codebuild-github-runners' \
--description 'GitHub fined-access token' \
--secret-string '{
"ServerType":"GITHUB",
"AuthType":"PERSONAL_ACCESS_TOKEN",
"Token":"<GH_PAT>"
}' \
--tags Key=codebuild:source,Value='' \
Key=codebuild:source:type,Value='github' \
Key=codebuild:source:provider,Value='personal_access_token'
The CodeBuild environment is defined by the codebuild_project_environment
input variable. Default values are suitable for most of the cases.
- Valid values for
codebuild_project_environment.compute_type
can be found in the official documentation foraws_codebuild_project
resource. See Build environment compute modes and types for furhter information such as memory, vCPUs and disk space. - Valid values for
codebuild_project_environment.image
can be found in Compute images supported with the CodeBuild-hosted GitHub Actions runner. For the source code see AWS CodeBuild curated Docker images. - Valid values for
codebuild_project_environment.type
can be found in the official documentation foraws_codebuild_project
resource
This module is designed to create a CodeBuild project inside a VPC and provides access to private resources. The specified VPC must meet the following requirements:
- The subnet used by the CodeBuild project must provide outbound access. Private subnets with a NAT Gateway are highly recommended.
- The attached Security Group to the CodeBuild project must provide only outbound access to Internet.
For a full checklist see best practices for VPCs.
In your GitHub Actions workflow YAML, you can provide a variety of label overrides that modify your self-hosted runner build. Any builds not recognized by CodeBuild will be ignored but will not fail your webhook request.
CodeBuild allows you to provide multiple overrides in a single label, for example:
runs-on: codebuild-<project-name>-${{ github.run_id }}-${{ github.run_attempt }}-<environment-type>-<image-identifier>-<instance-size>
To override the instance size to BUILD_GENERAL1_MEDIUM
, set
runs-on: codebuild-<project-name>-${{ github.run_id }}-${{ github.run_attempt }}-medium
module "codebuild_github_runners" {
source = "../"
codebuild_project_name = "ghSelfhostedRunners"
codebuild_project_description = "Uses CodeBuild to run GitHub Self-hosted Runners."
github_organization_name = "myorg"
pat_aws_secret_name = "aws-codebuild-github-runners"
aws_region = "eu-west-1"
codebuild_vpc_config = {
security_group_ids = ["sg-abc"]
subnets = ["subnet-abc", "subnet-def", "subnet-ghi"]
vpc_id = "vpc-abc"
}
tags = {
Project = "CodeBuild GitHub Runners"
TerraformModule = "codebuild_github_runners"
Environment = "Integrations"
}
}
Name | Version |
---|---|
terraform | >=1.5 |
aws | >=5.63.0 |
Name | Version |
---|---|
aws | 5.63.0 |
No modules.
Name | Type |
---|---|
aws_codebuild_project.this | resource |
aws_codebuild_webhook.this | resource |
aws_iam_policy.base | resource |
aws_iam_policy.codebuild_cw_logs | resource |
aws_iam_policy.codebuild_s3_logs | resource |
aws_iam_policy.codebuild_vpc | resource |
aws_iam_policy.secret_manager | resource |
aws_iam_role.codebuild | resource |
aws_iam_role_policy_attachment.base | resource |
aws_iam_role_policy_attachment.codebuild_cw_logs | resource |
aws_iam_role_policy_attachment.codebuild_s3_logs | resource |
aws_iam_role_policy_attachment.codebuild_vpc | resource |
aws_iam_role_policy_attachment.secret_manager | resource |
aws_caller_identity.current | data source |
aws_secretsmanager_secret.pat | data source |
Name | Description | Type | Default | Required |
---|---|---|---|---|
aws_region | The AWS region to provision the resources. | string |
n/a | yes |
codebuild_logs_config | CodeBuild logs configuration.cloudwatch_logs : (Optional) Configuration to store logs on AWS CloudWatch.- status : Current status of logs in CloudWatch Logs for a build project. Valid values: ENABLED , DISABLED .- group_name : Group name of the logs in CloudWatch Logs.- stream_name : Prefix of the log stream name of the logs in CloudWatch Logs.s3_logs : (Optional) Configuration to store logs on AWS S3.- status : Current status of logs in S3 for a build project. Valid values: ENABLED , DISABLED .- location : Name of the S3 bucket and the path prefix for S3 logs. Must be set if status is ENABLED, otherwise it must be empty.- encryption_disabled : Whether to disable encrypting S3 logs. |
object({ |
{} |
no |
codebuild_project_description | The description of the CodeBuild build project. | string |
n/a | yes |
codebuild_project_environment | The CodeBuild environment configuration.compute_type : (Required) Information about the compute resources the build project will use.image : (Required) Docker image to use for this build project.Valid values include Docker images provided by CodeBuild, DockerHub images and full Docker repository URIs such as those for ECR. type : (Required) Type of build environment to use for related builds.image_pull_credentials_type : (Optional) Type of credentials AWS CodeBuild uses to pull images in your build.privileged_mode : (Optional) Whether to enable running the Docker daemon inside a Docker container. |
object({ |
{ |
no |
codebuild_project_name | The name of the CodeBuild build project. | string |
n/a | yes |
codebuild_vpc_config | The VPC configuration to provision the CodeBuild Runners.security_group_ids : (Required) Security group IDs to assign to running builds.subnets : (Required) Subnet IDs within which to run builds.vpc_id : (Required) ID of the VPC within which to run builds. |
object({ |
n/a | yes |
github_organization_name | The name of the GitHub organization to add the webhook for AWS CodeBuild Runners. | string |
n/a | yes |
pat_aws_secret_name | The name of the AWS Secret Manager secret with the personal access token with access to GitHub. | string |
"" |
no |
tags | Tags added to all supported resources. | map(any) |
{} |
no |
Name | Description |
---|---|
codebuild_webhook_payload_url | The CodeBuild endpoint where webhook events are sent. |
codebuild_webhook_url | The URL to the webhook. |