Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions CHANGELOG.md

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions README.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ To be able to support a number of use-cases, the module has quite a lot of confi
- Multi-Runner module. This modules allows you to create multiple runner configurations with a single webhook and single GitHub App to simplify deployment of different types of runners. Check the detailed module [documentation](modules/public/multi-runner.md) for more information or checkout the [multi-runner example](examples/multi-runner.md).
- Webhook mode, the module can be deployed in `direct` mode or `EventBridge` (Experimental) mode. The `direct` mode is the default and will directly distribute to SQS for the scale-up lambda. The `EventBridge` mode will publish the events to a eventbus, the rule then directs the received events to a dispatch lambda. The dispatch lambda will send the event to the SQS queue. The `EventBridge` mode is the default and allows to have more control over the events and potentially filter them. The `EventBridge` mode can be disabled, messages are sent directed to queues in that case. An example of what the `EventBridge` mode could be used for is building a data lake, build metrics, act on `workflow_job` job started events, etc.
- Linux vs Windows. You can configure the OS types linux and win. Linux will be used by default.
- Re-use vs Ephemeral. By default runners are re-used, until detected idle. Once idle they will be removed from the pool. To improve security we are introducing ephemeral runners. Those runners are only used for one job. Ephemeral runners only work in combination with the workflow job event. For ephemeral runners the lambda requests a JIT (just in time) configuration via the GitHub API to register the runner. [JIT configuration](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-just-in-time-runners) is limited to ephemeral runners (and currently not supported by GHES). For non-ephemeral runners, a registration token is always requested. In both cases the configuration is made available to the instance via the same SSM parameter. To disable JIT configuration for ephemeral runners set `enable_jit_config` to `false`. We also suggest using a pre-build AMI to improve the start time of jobs for ephemeral runners.
- Reuse vs Ephemeral. By default runners are reused, until detected idle. Once idle they will be removed from the pool. To improve security we are introducing ephemeral runners. Those runners are only used for one job. Ephemeral runners only work in combination with the workflow job event. For ephemeral runners the lambda requests a JIT (just in time) configuration via the GitHub API to register the runner. [JIT configuration](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-just-in-time-runners) is limited to ephemeral runners (and currently not supported by GHES). For non-ephemeral runners, a registration token is always requested. In both cases the configuration is made available to the instance via the same SSM parameter. To disable JIT configuration for ephemeral runners set `enable_jit_config` to `false`. We also suggest using a pre-build AMI to improve the start time of jobs for ephemeral runners.
- Job retry (**Beta**). By default the scale-up lambda will discard the message when it is handled. Meaning in the ephemeral use-case an instance is created. The created runner will ask GitHub for a job, no guarantee it will run the job for which it was scaling. Result could be that with small system hick-up the job is keeping waiting for a runner. Enable a pool (org runners) is one option to avoid this problem. Another option is to enable the job retry function. Which will retry the job after a delay for a configured number of times.
- GitHub Cloud vs GitHub Enterprise Server (GHES). The runners support GitHub Cloud (Public GitHub - github.com), GitHub Data Residency instances (ghe.com), and GitHub Enterprise Server. For GHES, we rely on our community for support and testing. We have no capability to test GHES ourselves.
- Spot vs on-demand. The runners use either the EC2 spot or on-demand life cycle. Runners will be created via the AWS [CreateFleet API](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateFleet.html). The module (scale up lambda) will request via the CreateFleet API to create instances in one of the subnets and of the specified instance types.
Expand Down Expand Up @@ -286,7 +286,7 @@ In case the setup does not work as intended, trace the events through this seque

This feature is in early stage and therefore disabled by default. To enable the watcher, set `instance_termination_watcher.enable = true`.

The termination watcher is currently watching for spot terminations. The module is only taken events into account for instances tagged with `ghr:environment` by default when deployment the module as part of one of the main modules (root or multi-runner). The module can also be deployed stand-alone, in this case, the tag filter needs to be tunned.
The termination watcher is currently watching for spot terminations. The module is only taken events into account for instances tagged with `ghr:environment` by default when deployment the module as part of one of the main modules (root or multi-runner). The module can also be deployed stand-alone, in this case, the tag filter needs to be tuned.

### Termination notification

Expand Down Expand Up @@ -352,7 +352,7 @@ locals {

resource "aws_cloudwatch_event_rule" "example" {
name = "${local.prefix}-github-events-all"
description = "Caputure all GitHub events"
description = "Capture all GitHub events"
event_bus_name = local.event_bus_name
event_pattern = <<EOF
{
Expand Down
2 changes: 1 addition & 1 deletion examples/ephemeral/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ module "runners" {
# Enable debug logging for the lambda functions
# log_level = "debug"

# Setup a dead letter queue, by default scale up lambda will kepp retrying to process event in case of scaling error.
# Setup a dead letter queue, by default scale up lambda will keep retrying to process event in case of scaling error.
# redrive_policy_build_queue = {
# enabled = true
# maxReceiveCount = 50 # 50 retries every 30 seconds => 25 minutes
Expand Down
2 changes: 1 addition & 1 deletion examples/external-managed-ssm-secrets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Example using AWS CLI:

Steps for the full setup, such as creating a GitHub app can be found in the root module's [README](https://github.com/philips-labs/terraform-aws-github-runner). First download the Lambda releases from GitHub. Alternatively you can build the lambdas locally with Node or Docker, there is a simple build script in `<root>/.ci/build.sh`. In the `main.tf` you can simply remove the location of the lambda zip files, the default location will work in this case.

> This example assumes local built lambda's available. Ensure you have built the lambda's. Alternativly you can downlowd the lambda's. The version needs to be set to a GitHub release version, see https://github.com/philips-labs/terraform-aws-github-runner/releases
> This example assumes local built lambda's available. Ensure you have built the lambda's. Alternatively you can download the lambda's. The version needs to be set to a GitHub release version, see https://github.com/philips-labs/terraform-aws-github-runner/releases

```bash
cd ../lambdas-download
Expand Down
2 changes: 1 addition & 1 deletion examples/prebuilt/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ module "runners" {

# `schedule_expression`: is used to configure the schedule for the lambda.
# `enabled`: enable or disable the lambda trigger via the EventBridge.
# `lambda_memory_size`: lambda memery size limit.
# `lambda_memory_size`: lambda memory size limit.
# `lambda_timeout`: timeout for the lambda in seconds.
# `config`: configuration for the lambda function. Token path will be read by default from the module.
# EOF
Expand Down
4 changes: 2 additions & 2 deletions examples/termination-watcher/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This module shows how to use the termination watcher stand-alone.

## Usages

Esnure your have the lambda for the termination locally build. By default the one in the lambdas folder will be used.
Ensure your have the lambda for the termination locally build. By default the one in the lambdas folder will be used.

Build lambda's (requires node and yarn).

Expand All @@ -20,7 +20,7 @@ terraform init
terraform apply
```

Once a Spot instance is terminated a log line and metric will be updated. Spot instance termination can be simulated using the Amazon [Fault Injection Service](https://docs.aws.amazon.com/fis/latest/userguide/what-is.html) (FIS). In thw web console you can simply initiate a spot instance failure by navigate in the EC2 console to Spot Requests and choose the action initiate a spot termination event.
Once a Spot instance is terminated a log line and metric will be updated. Spot instance termination can be simulated using the Amazon [Fault Injection Service](https://docs.aws.amazon.com/fis/latest/userguide/what-is.html) (FIS). In the web console you can simply initiate a spot instance failure by navigate in the EC2 console to Spot Requests and choose the action initiate a spot termination event.

<!-- BEGIN_TF_DOCS -->
## Requirements
Expand Down
2 changes: 1 addition & 1 deletion images/install-runner.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

user_name=ec2-user

## This wrapper file re-uses scripts in the /modules/runners/templates directory
## This wrapper file reuses scripts in the /modules/runners/templates directory
## of this repo. These are the same that are used by the user_data functionality
## to bootstrap the instance if it is started from an existing AMI.
${install_runner}
2 changes: 1 addition & 1 deletion images/install-runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

user_name=$(cat /tmp/install-user.txt)

## This wrapper file re-uses scripts in the /modules/runners/templates directory
## This wrapper file reuses scripts in the /modules/runners/templates directory
## of this repo. These are the same that are used by the user_data functionality
## to bootstrap the instance if it is started from an existing AMI.
${install_runner}
2 changes: 1 addition & 1 deletion images/start-runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ exec > >(tee /var/log/runner-startup.log | logger -t user-data -s 2>/dev/console

cd /opt/actions-runner

## This wrapper file re-uses scripts in the /modules/runners/templates directory
## This wrapper file reuses scripts in the /modules/runners/templates directory
## of this repo. These are the same that are used by the user_data functionality
## to bootstrap the instance if it is started from an existing AMI.
${start_runner}
2 changes: 1 addition & 1 deletion images/windows-core-2019/windows-provisioner.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Write-Host "Installing additional development tools"
choco install git awscli -y
refreshenv

Write-Host "Creating actions-runner directory for the GH Action installtion"
Write-Host "Creating actions-runner directory for the GH Action installation"
New-Item -ItemType Directory -Path C:\actions-runner ; Set-Location C:\actions-runner

Write-Host "Downloading the GH Action runner from ${action_runner_url}"
Expand Down
2 changes: 1 addition & 1 deletion images/windows-core-2022/windows-provisioner.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Write-Host "Installing additional development tools"
choco install git awscli -y
refreshenv

Write-Host "Creating actions-runner directory for the GH Action installtion"
Write-Host "Creating actions-runner directory for the GH Action installation"
New-Item -ItemType Directory -Path C:\actions-runner ; Set-Location C:\actions-runner

Write-Host "Downloading the GH Action runner from ${action_runner_url}"
Expand Down
2 changes: 1 addition & 1 deletion lambdas/functions/ami-housekeeper/src/lambda.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ describe('Housekeeper ami', () => {
await expect(handler(undefined, context)).resolves.not.toThrow();
});

it('should not thow only log in error in case of an exception.', async () => {
it('should not throw only log in error in case of an exception.', async () => {
const logSpy = vi.spyOn(logger, 'error');

const error = new Error('An error.');
Expand Down
6 changes: 3 additions & 3 deletions lambdas/functions/control-plane/src/aws/runners.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ describe('create runner with errors fail over to OnDemand', () => {

expect(mockEC2Client).toHaveReceivedCommandTimes(CreateFleetCommand, 2);

// first call with spot failuer
// first call with spot failure
expect(mockEC2Client).toHaveReceivedNthCommandWith(1, CreateFleetCommand, {
...expectedCreateFleetRequest({
...defaultExpectedFleetRequestValues,
Expand Down Expand Up @@ -555,7 +555,7 @@ describe('create runner with errors fail over to OnDemand', () => {

expect(mockEC2Client).toHaveReceivedCommandTimes(CreateFleetCommand, 2);

// first call with spot failuer
// first call with spot failure
expect(mockEC2Client).toHaveReceivedNthCommandWith(1, CreateFleetCommand, {
...expectedCreateFleetRequest({
...defaultExpectedFleetRequestValues,
Expand Down Expand Up @@ -585,7 +585,7 @@ describe('create runner with errors fail over to OnDemand', () => {

expect(mockEC2Client).toHaveReceivedCommandTimes(CreateFleetCommand, 1);

// first call with spot failuer
// first call with spot failure
expect(mockEC2Client).toHaveReceivedNthCommandWith(1, CreateFleetCommand, {
...expectedCreateFleetRequest({
...defaultExpectedFleetRequestValues,
Expand Down
2 changes: 1 addition & 1 deletion lambdas/functions/control-plane/src/pool/pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export async function adjust(event: PoolEvent): Promise<void> {
const ghAuth = await createGithubInstallationAuth(installationId, ghesApiUrl);
const githubInstallationClient = await createOctokitClient(ghAuth.token, ghesApiUrl);

// Get statusses of runners registed in GitHub
// Get statuses of runners registered in GitHub
const runnerStatusses = await getGitHubRegisteredRunnnerStatusses(
githubInstallationClient,
runnerOwner,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ describe('scaleUp with GHES', () => {
expect(createRunner).toBeCalledWith({ ...expectedRunnerParams, amiIdSsmParameterName: 'my-ami-id-param' });
});

it('Throws an error if runner group doesnt exist for ephemeral runners', async () => {
it('Throws an error if runner group does not exist for ephemeral runners', async () => {
process.env.RUNNER_GROUP_NAME = 'test-runner-group';
mockSSMgetParameter.mockImplementation(async () => {
throw new Error('ParameterNotFound');
Expand All @@ -266,7 +266,7 @@ describe('scaleUp with GHES', () => {
expect(createRunner).not.toHaveBeenCalled();
});

it('create SSM parameter for runner group id if it doesnt exist', async () => {
it('create SSM parameter for runner group id if it does not exist', async () => {
mockSSMgetParameter.mockImplementation(async () => {
throw new Error('ParameterNotFound');
});
Expand Down Expand Up @@ -784,7 +784,7 @@ describe('scaleUp with Github Data Residency', () => {
expect(createRunner).toBeCalledWith({ ...expectedRunnerParams, amiIdSsmParameterName: 'my-ami-id-param' });
});

it('Throws an error if runner group doesnt exist for ephemeral runners', async () => {
it('Throws an error if runner group does not exist for ephemeral runners', async () => {
process.env.RUNNER_GROUP_NAME = 'test-runner-group';
mockSSMgetParameter.mockImplementation(async () => {
throw new Error('ParameterNotFound');
Expand All @@ -801,7 +801,7 @@ describe('scaleUp with Github Data Residency', () => {
expect(createRunner).not.toHaveBeenCalled();
});

it('create SSM parameter for runner group id if it doesnt exist', async () => {
it('create SSM parameter for runner group id if it does not exist', async () => {
mockSSMgetParameter.mockImplementation(async () => {
throw new Error('ParameterNotFound');
});
Expand Down
2 changes: 1 addition & 1 deletion lambdas/functions/webhook/src/lambda.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ vi.mock('@aws-github-runner/aws-ssm-util');
describe('Test webhook lambda wrapper.', () => {
beforeEach(() => {
// We mock all SSM request to resolve to a non empty array. Since we mock all implemeantions
// relying on the config opbject that is enought to test the handlers.
// relying on the config object that is enough to test the handlers.
const mockedGet = vi.mocked(getParameter);
mockedGet.mockResolvedValue('["abc"]');
vi.clearAllMocks();
Expand Down
2 changes: 1 addition & 1 deletion lambdas/functions/webhook/src/runners/dispatch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ describe('Dispatcher', () => {
expect(canRunJob(workflowLabels, runnerLabels, false)).toBe(true);
});

it('should NOT accept job with for an exact match. Not all requested capabilites are supported.', () => {
it('should NOT accept job with for an exact match. Not all requested capabilities are supported.', () => {
const workflowLabels = ['self-hosted', 'linux', 'x64', 'ubuntu-latest', 'gpu'];
const runnerLabels = [['gpu']];
expect(canRunJob(workflowLabels, runnerLabels, true)).toBe(false);
Expand Down
2 changes: 1 addition & 1 deletion lambdas/functions/webhook/src/webhook/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ describe('handle GitHub webhook events', () => {
});
});

it('should throw if publish to bridge failes.,', async () => {
it('should throw if publish to bridge fails.,', async () => {
// setup
vi.mocked(publish).mockRejectedValue(new Error('test'));
const event = JSON.stringify(workFlowJobEvent);
Expand Down
Loading
Loading