This repository contains Dockerfiles for self-hosted GitHub Actions runners and an associated Terraform module, github-actions-runner-terraform
, which can be run in your environment to provision:
- ECS Cluster
- ECS Service
- ECS Fargate task definition to spin up an instance of this runner per job in your GitHub Actions workflow
This module uses the ECR repository created in the MACBIS Shared DSO Dev account, managed in the terraform/dev/account
directory, and accessible by the MACBIS organization.
latest.Dockerfile
: A minimal runner image based on Ubuntu. Reference this image with thelatest
image tagplaywright.Dockerfile
: An image using theplaywright:focal
base image for Playwright dependencies. Reference this image with theplaywright-v{semver}
image tag, where{semver}
is the semantic version of the Playwright base image defined in theplaywright.Dockerfile
The current version of the runner is stored in docker.env
as ACTIONS_VERSION
. To build the Dockerfiles locally, you must first export this environment variable, then tell Docker to use it as a build argument from the environment, like so:
export $(cat docker.env) && docker build -f latest.Dockerfile --build-arg ACTIONS_VERSION -t local-latest .
See Confluence for setup steps.
The github-oidc
module that configures the IAM resources necessary to use GitHub's OIDC provider to retrieve short-term credentials from AWS is DEPRECATED. Use the official AWS OIDC role and identity provider modules. See the confluence page for setting up a self-hosted runner for more information.
This is strictly for testing purposes. These steps help test a Github token by running the docker image and enabling you to manually trigger the entrypoint.sh
script locally via Docker. This does not require any AWS infrastructure deployed.
The entrypoint.sh
script is what sets up the docker image to act as a runner, including registration with the repository specified.
- Clone this repository to your machine.
- Ensure your environment variables are populated:
PERSONAL_ACCESS_TOKEN
- Your GitHub personal access token with repository permissions.REPO_OWNER
- The name of the repository owner, e.g.Enterprise-CMCS
REPO_NAME
- The name of the repository you are configuring the runners for
- Build and run the image.
./entrypoint.sh
should register the runner with your repository and start listening for jobs. - In one of the workflows in the target repository, change the
runs-on
value toself-hosted
. This will make the workflow use the registered self-hosted runner to complete its task, after which it will shut down.
This repository contains a Terraform module github-actions-runner-terraform
to deploy an ECS cluster, ECS service, and log to Cloudwatch in support of automating the deployment of ephemeral self-hosted Github Actions runners within AWS.
This module supports the following features:
- Optionally pass an existing ECS Cluster, and if not, create one
- Set default desired count for ECS Service (default is 0, assuming it will be managed by Github Actions workflow)
- If you don't want the workflow to start and stop the ECS service then set the desired count to
1
so that the ECS service is always running.
See the instructions on the confluence page Setting up a Self-Hosted GitHub Actions Runner.
module "github-actions-runner-aws" {
source = "github.com/Enterprise-CMCS/mac-fc-github-actions-runner-aws//github-actions-runner-terraform?ref=v5.0.0"
# ECS variables
environment = "${environment}"
ecs_vpc_id = "${vpc.id}"
ecs_subnet_ids = "${vpc.private_subnets.id}"
# GitHub Runner variables
personal_access_token_arn = "aws_secretsmanager_secret_version.this.arn"
github_repo_name = "${repo_name}"
github_repo_owner = "${repo_owner}"
# IAM variables
role_path = "/delegatedadmin/developer/"
permissions_boundary = "arn:aws:iam::{your AWS account ID}:policy/cms-cloud-admin/developer-boundary-policy"
}
resource "aws_secretsmanager_secret" "this" {
description = "Secret to store github access token"
name = "/github-runner-token"
}
resource "aws_secretsmanager_secret_version" "this" {
secret_id = aws_secretsmanager_secret.this.id
secret_string = "placeholder"
lifecycle {
ignore_changes = [
secret_string
]
}
}
Some existing variable information can be looked-up in AWS via data sources. For example:
data "aws_secretsmanager_secret_version" "token" {
secret_id = "/github-runner-dev/token"
}
Will let you then use the ARN of that data source in this way:
personal_access_token_arn = data.aws_secretsmanager_secret_version.token.arn
Name | Description |
---|---|
environment | Environment name (used in naming resources) |
ecs_vpc_id | VPC ID to be used by ECS |
ecs_subnet_ids | Subnet IDs for the ECS tasks. |
personal_access_token_arn | AWS SecretsManager ARN for GitHub personal access token |
github_repo_name | The Github repository name |
Name | Default Value | Description |
---|---|---|
cloudwatch_log_retention | 731 | Number of days to retain Cloudwatch logs |
ecr_repo_tag | "latest" | The tag to identify and pull the image in ECR repo |
ecs_desired_count | 0 | Sets the default desired count for task definitions within the ECS service |
assign_public_ip | "false" | Choose whether to assign a public IP address to the Elastic Network Interface |
role_path | "/" | The path in which to create the assume roles and policies. Refer to the AWS docs for more |
permissions_boundary | "" | ARN of the policy that is used to set the permissions boundary for the role |
github_repo_owner | "Enterprise-CMCS" | The name of the Github repo owner |
tags | {} | Additional tags to apply |
runner_labels | "" | A comma-separated list of labels to apply to the runner |
See outputs.tf
Name | Version |
---|---|
terraform | >= 0.13 |
aws | >= 3.0 |
None.