Skip to content

Commit

Permalink
Introduce jit config runner registration
Browse files Browse the repository at this point in the history
  • Loading branch information
Tereius committed Aug 2, 2024
1 parent 93614d7 commit 13d9b18
Show file tree
Hide file tree
Showing 7 changed files with 237 additions and 79 deletions.
8 changes: 6 additions & 2 deletions cloudRun.tf
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,12 @@ resource "google_cloud_run_v2_service" "autoscaler" {
value = var.github_runner_prefix
}
env {
name = "RUNNER_GROUP"
value = var.github_runner_group
name = "RUNNER_GROUP_NAME"
value = var.github_runner_group_name
}
env {
name = "RUNNER_GROUP_ID"
value = var.github_runner_group_id
}
env {
name = "RUNNER_LABELS"
Expand Down
37 changes: 35 additions & 2 deletions compute.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ resource "google_compute_instance_template" "runner_instance" {
}
}

// First parameter has to be the registration token
resource "google_compute_project_metadata_item" "startup_scripts_register_runner" {
key = "startup_script_register_runner"
value = <<EOT
Expand All @@ -49,13 +50,45 @@ apt-get update && apt-get -y install docker.io docker-buildx curl
useradd -d /home/agent -u 10000 agent
usermod -aG docker agent
newgrp docker
wget -q -O /tmp/agent.tar.gz '${var.github_runner_download_url}'
curl -s -o /tmp/agent.tar.gz -L '${var.github_runner_download_url}'
mkdir -p /home/agent
chown -R agent:agent /home/agent
pushd /home/agent
sudo -u agent tar zxf /tmp/agent.tar.gz
registration_token=$1
sudo -u agent ./config.sh --unattended --disableupdate --ephemeral --name $(hostname) ${local.runnerLabelInstanceTemplate} --url 'https://github.com/${var.github_organization}' --token $${registration_token} --runnergroup '${var.github_runner_group}' || shutdown now
sudo -u agent ./config.sh --unattended --disableupdate --ephemeral --name $(hostname) ${local.runnerLabelInstanceTemplate} --url 'https://github.com/${var.github_organization}' --token $${registration_token} --runnergroup '${var.github_runner_group_name}' || shutdown now
./bin/installdependencies.sh || shutdown now
./svc.sh install agent || shutdown now
./svc.sh start || shutdown now
popd
rm /tmp/agent.tar.gz
echo "Setup finished"
EOT
}

// First parameter has to be the base64 encoded jit_config
resource "google_compute_project_metadata_item" "startup_scripts_register_jit_runner" {
key = "startup_script_register_jit_runner"
value = <<EOT
#!/bin/bash
agent_name=$(hostname)
echo "Setup of agent '$agent_name' started"
apt-get update && apt-get -y install docker.io docker-buildx curl jq
useradd -d /home/agent -u 10000 agent
usermod -aG docker agent
newgrp docker
curl -s -o /tmp/agent.tar.gz -L '${var.github_runner_download_url}'
mkdir -p /home/agent
chown -R agent:agent /home/agent
pushd /home/agent
sudo -u agent tar zxf /tmp/agent.tar.gz
encoded_jit_config=$1
echo -n $encoded_jit_config | base64 -d | jq '.".runner"' -r | base64 -d > .runner
echo -n $encoded_jit_config | base64 -d | jq '.".credentials"' -r | base64 -d > .credentials
echo -n $encoded_jit_config | base64 -d | jq '.".credentials_rsaparams"' -r | base64 -d > .credentials_rsaparams
sed -i 's/{{SvcNameVar}}/actions.runner.${var.github_organization}.$${agent_name}.service/g' bin/systemd.svc.sh.template
sed -i 's/{{SvcDescription}}/GitHub Actions Runner (${var.github_organization}.$${agent_name})/g' bin/systemd.svc.sh.template
cp bin/systemd.svc.sh.template ./svc.sh && chmod +x ./svc.sh
./bin/installdependencies.sh || shutdown now
./svc.sh install agent || shutdown now
./svc.sh start || shutdown now
Expand Down
38 changes: 21 additions & 17 deletions runner-autoscaler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,30 @@ Following conditions of the workflow job webhook event have to be fulfilled, so

* The webhook signature is valid (see WEBHOOK_SECRET env).
* The webhook `action` value equals `completed`.
* The webhook `workflow_job.runner_group_name` value equals the configured RUNNER_GROUP.
* The webhook `workflow_job.runner_group_name` value equals the configured RUNNER_GROUP_NAME.
* **All** labels of the workflow job match the configured RUNNER_LABELS.

### Configuration

The scaler is configured via the following environment variables:

| Env | Default | Description |
| ----------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ROUTE_WEBHOOK | /webhook | The Cloud Run path that is invoked by the GitHub webhook. Depending on the workflow job, a Cloud Task "delete runner" or "create runner" is enqueued. |
| ROUTE_DELETE_VM | /delete_vm | The Cloud Run callback path invoked by Cloud Task when a VM instance should be **deleted**. The payload contains the name of the "to be deleted" VM instance. |
| ROUTE_CREATE_VM | /create_vm | The Cloud Run callback path invoked by Cloud Task when a VM instance should be **created**. The payload contains the name of the "to be created" VM instance. |
| WEBHOOK_SECRET | | The GitHub webhook secret. This is the secret the webhook has been [configured](https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries) with. |
| PROJECT_ID | | The Google Cloud Project Id. |
| ZONE | | The Google Cloud zone where the VM instance will be created. |
| TASK_QUEUE | | The relative resource name of the Cloud Task queue. |
| INSTANCE_TEMPLATE | | The relative resource name of the instance template from which the VM instance will be created. |
| SECRET_VERSION | | The relative resource name of the secret version which contains the PAT |
| RUNNER_PREFIX | runner | Prefix for the the name of a new VM instance. A random string (10 random lower case characters) will be added to make the name unique: "<prefix>-<random_string>". |
| RUNNER_GROUP | Default | The GitHub runner group where the VM instance is expected to join as a self hosted runner. |
| RUNNER_LABELS | self-hosted *(comma separated list)* | Only workflow jobs whose labels match **all** the configured labels will be taken into account. If only one configured label is **not** found in the workflow job it will be ignored. |
| GITHUB_ORG | | The name of the GitHub Organization |
| PORT | 8080 | To which port the webserver is bound. |
| Env | Default | Description |
| ----------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| ROUTE_WEBHOOK | /webhook | The Cloud Run path that is invoked by the GitHub webhook. Depending on the workflow job, a Cloud Task "delete runner" or "create runner" is enqueued. |
| ROUTE_DELETE_VM | /delete_vm | The Cloud Run callback path invoked by Cloud Task when a VM instance should be **deleted**. The payload contains the name of the "to be deleted" VM instance. |
| ROUTE_CREATE_VM | /create_vm | The Cloud Run callback path invoked by Cloud Task when a VM instance should be **created**. The payload contains the name of the "to be created" VM instance. |
| WEBHOOK_SECRET | | The GitHub webhook secret. This is the secret the webhook has been [configured](https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries) with. |
| PROJECT_ID | | The Google Cloud Project Id. |
| ZONE | | The Google Cloud zone where the VM instance will be created. |
| TASK_QUEUE | | The relative resource name of the Cloud Task queue. |
| INSTANCE_TEMPLATE | | The relative resource name of the instance template from which the VM instance will be created. |
| SECRET_VERSION | | The relative resource name of the secret version which contains the PAT |
| RUNNER_PREFIX | runner | Prefix for the the name of a new VM instance. A random string (10 random lower case characters) will be added to make the name unique: "<prefix>-<random_string>". |
| RUNNER_GROUP_NAME | Default | The GitHub runner group name where the VM instance is expected to join as a self hosted runner. |
| RUNNER_GROUP_ID | 0 | (optional - but preferred) The GitHub runner group ID where the VM instance is expected to join as a self hosted runner (must be the ID of the **same** runner group with the name RUNNER_GROUP_NAME). |
| RUNNER_LABELS | self-hosted *(comma separated list)* | Only workflow jobs whose labels match **all** the configured labels will be taken into account. If only one configured label is **not** found in the workflow job it will be ignored. |
| GITHUB_ORG | | The name of the GitHub Organization |
| PORT | 8080 | To which port the webserver is bound. |

> [!IMPORTANT]
> If RUNNER_GROUP_ID is set to a value **greater than 0** the VM instance will use a **jit config** to register itself as a GitHub runner. Else the VM instance will use a registration token to register itself as a GitHub runner.
6 changes: 4 additions & 2 deletions runner-autoscaler/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ func main() {
logrus.SetLevel(logrus.InfoLevel)

labels := strings.Split(getEnvDefault("RUNNER_LABELS", "self-hosted"), ",")
runnerGroup := getEnvDefault("RUNNER_GROUP", "Default")
runnerGroup := getEnvDefault("RUNNER_GROUP_NAME", "Default")
runnerGroupId, _ := strconv.Atoi(getEnvDefault("RUNNER_GROUP_ID", "0"))
scaler := pkg.NewAutoscaler(pkg.AutoscalerConfig{
RouteWebhook: getEnvDefault("ROUTE_WEBHOOK", "/webhook"),
RouteDeleteVm: getEnvDefault("ROUTE_DELETE_VM", "/delete_vm"),
Expand All @@ -50,7 +51,8 @@ func main() {
InstanceTemplate: mustGetEnv("INSTANCE_TEMPLATE"),
SecretVersion: mustGetEnv("SECRET_VERSION"),
RunnerPrefix: getEnvDefault("RUNNER_PREFIX", "runner"),
RunnerGroup: runnerGroup,
RunnerGroupName: runnerGroup,
RunnerGroupId: runnerGroupId,
RunnerLabels: labels,
GitHubOrg: mustGetEnv("GITHUB_ORG"),
})
Expand Down
Loading

0 comments on commit 13d9b18

Please sign in to comment.