diff --git a/examples/arm64/README.md b/examples/arm64/README.md index 3573839c5c..2c198d6a8b 100644 --- a/examples/arm64/README.md +++ b/examples/arm64/README.md @@ -52,6 +52,7 @@ Be aware some shells will print some end of line character `%`. |------|--------|---------| | [base](#module\_base) | ../base | n/a | | [runners](#module\_runners) | ../../ | n/a | +| [webhook-github-app](#module\_webhook-github-app) | ../../modules/webhook-github-app | n/a | ## Resources diff --git a/examples/arm64/main.tf b/examples/arm64/main.tf index f725649336..44fad85bc6 100644 --- a/examples/arm64/main.tf +++ b/examples/arm64/main.tf @@ -86,3 +86,14 @@ module "runners" { # override scaling down scale_down_schedule_expression = "cron(* * * * ? *)" } + +module "webhook-github-app" { + source = "../../modules/webhook-github-app" + + github_app = { + key_base64 = var.github_app.key_base64 + id = var.github_app.id + webhook_secret = random_id.random.hex + } + webhook_endpoint = module.runners.webhook.endpoint +} diff --git a/examples/default/README.md b/examples/default/README.md index c2f5f94313..90dd8006f0 100644 --- a/examples/default/README.md +++ b/examples/default/README.md @@ -22,14 +22,12 @@ terraform init terraform apply ``` -You can receive the webhook details by running: +The module will try to update the GitHub App webhook and secret (only linux/mac). You can receive the webhook details by running: ```bash -terraform output -raw webhook_secret +terraform output webhook_secret ``` -Be aware some shells will print some end of line character `%`. - ## Requirements @@ -52,6 +50,7 @@ Be aware some shells will print some end of line character `%`. |------|--------|---------| | [base](#module\_base) | ../base | n/a | | [runners](#module\_runners) | ../../ | n/a | +| [webhook-github-app](#module\_webhook-github-app) | ../../modules/webhook-github-app | n/a | ## Resources diff --git a/examples/default/main.tf b/examples/default/main.tf index e4dca90521..2acdaf91ba 100644 --- a/examples/default/main.tf +++ b/examples/default/main.tf @@ -97,3 +97,14 @@ module "runners" { # Enable debug logging for the lambda functions # log_level = "debug" } + +module "webhook-github-app" { + source = "../../modules/webhook-github-app" + + github_app = { + key_base64 = var.github_app.key_base64 + id = var.github_app.id + webhook_secret = random_id.random.hex + } + webhook_endpoint = module.runners.webhook.endpoint +} diff --git a/examples/ephemeral/README.md b/examples/ephemeral/README.md index 53b26d8dc3..2562bda22a 100644 --- a/examples/ephemeral/README.md +++ b/examples/ephemeral/README.md @@ -21,13 +21,12 @@ terraform init terraform apply ``` -You can receive the webhook details by running: +The module will try to update the GitHub App webhook and secret (only linux/mac). You can receive the webhook details by running: ```bash -terraform output -raw webhook_secret +terraform output webhook_secret ``` -Be aware some shells will print some end of line character `%`. ## Requirements @@ -50,6 +49,7 @@ Be aware some shells will print some end of line character `%`. |------|--------|---------| | [base](#module\_base) | ../base | n/a | | [runners](#module\_runners) | ../../ | n/a | +| [webhook-github-app](#module\_webhook-github-app) | ../../modules/webhook-github-app | n/a | ## Resources diff --git a/examples/ephemeral/main.tf b/examples/ephemeral/main.tf index fbbc588178..4346a351bd 100644 --- a/examples/ephemeral/main.tf +++ b/examples/ephemeral/main.tf @@ -85,3 +85,14 @@ module "runners" { # deadLetterTargetArn = null # } } + +module "webhook-github-app" { + source = "../../modules/webhook-github-app" + + github_app = { + key_base64 = var.github_app.key_base64 + id = var.github_app.id + webhook_secret = random_id.random.hex + } + webhook_endpoint = module.runners.webhook.endpoint +} diff --git a/examples/multi-runner/.terraform.lock.hcl b/examples/multi-runner/.terraform.lock.hcl index e58658f11f..433917f00d 100644 --- a/examples/multi-runner/.terraform.lock.hcl +++ b/examples/multi-runner/.terraform.lock.hcl @@ -2,26 +2,25 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/aws" { - version = "5.2.0" + version = "5.13.1" constraints = ">= 5.0.0, ~> 5.2" hashes = [ - "h1:KMTZaIU2/3+cQICzsReZf2mE9FytDc7/iA1i669gyHI=", - "h1:NB70SyXuleF41iKoGtzs61f8xZtGJ+M4bxFI0DeHOzg=", - "zh:0e48449e9f29b64663e7ff641a3ba1da434608460c33a20bdb45efeb1e067d4a", - "zh:0ec657a1e586087368cc3051ccb8bdf67e8763e50eece76b8dc4695f8d349ebb", - "zh:1cff541e792477c4dc8b8405a6f76a56d1292e23d6fc367993efed2b3988c208", - "zh:312e7c0c56742cb83d18cb2a3f2da35f4d92481353b0ac2b54d6333df91c2399", - "zh:352bc8a73fdb829306c141fffcb170172c7860c9fff0e02239ef8c771b3468a3", - "zh:4d5403f8d5a8da4db6bcf9d8b60fc790b2f2e1cf49438bb2c3f6c2ccbfa672cb", - "zh:4d90c9a759778a55274f05f69c8b38a2d0d1def792bb556ac6194e5979653f55", - "zh:9033d03e08967bf1ebb420cb1f6e77750a7aa75036a53a0b6709fdc107a829d9", + "h1:T/p3Gp8uAvRk3BmBZI/B7JIUpxF+2DygvBsv2UvJK4w=", + "zh:0d107e410ecfbd5d2fb5ff9793f88e2ce03ae5b3bda4e3b772b5d146cdd859d8", + "zh:1080cf6a402939ec4ad393380f2ab2dfdc0e175903e08ed796aa22eb95868847", + "zh:300420d642c3ada48cfe633444eafa7bcd410cd6a8503de2384f14ac54dc3ce3", + "zh:4e0121014a8d6ef0b1ab4634877545737bb54e951340f1b67ffea8cd22b2d252", + "zh:59b401bbf95dc8c6bea58085ff286543380f176271251193eac09cb7fcf619b7", + "zh:5dfaf51e979131710ce8e1572e6012564e68c7c842e3d9caaaeb0fe6af15c351", + "zh:84bb75dafca056d7c3783be5185187fdd3294f902e9d72f7655f2efb5e066650", "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", - "zh:a8cbffecf5f128081cf62dbd6e2d68105031d08c3499e34dcb6692cc147dec9d", - "zh:bf0778aa0b53e3e65c25fdc4f1b639f4082a01226400958e4135630e2d132d56", - "zh:c9da1ae68faa4bc9f585d175eb666cbfcddafcdcfd6a18f3ecd071631fb4d4c5", - "zh:cbc04edd7a868cf2713fd301ca357adb940003d0c02f5351c987e2ab6ead2a46", - "zh:dae64f3047f18fabe7c5e9d6bccfb7f4b4793994cea0947dc1ac17e1922bf715", - "zh:f7bad3983479af95b5b1cbe43305fa6492222cc4f17a512677dfab7c98cc480c", + "zh:aa4e2b9f699d497041679bc05ca34ac21a5184298eb1813f35455b1883977910", + "zh:b51a4f08d84b071128df68a95cfa5114301a50bf8ab8e655dcf7e384e5bc6458", + "zh:bce284ac6ebb65053d9b703048e3157bf4175782ea9dbaec9f64dc2b6fcefb0c", + "zh:c748f78b79b354794098b06b18a02aefdb49be144dff8876c9204083980f7de0", + "zh:ee69d9aef5ca532392cdc26499096f3fa6e55f8622387f78194ebfaadb796aef", + "zh:ef561bee58e4976474bc056649095737fa3b2bcb74602032415d770bfc620c1f", + "zh:f696d8416c57c31f144d432779ba34764560a95937db3bb3dd2892a791a6d5a7", ] } @@ -46,6 +45,25 @@ provider "registry.terraform.io/hashicorp/local" { ] } +provider "registry.terraform.io/hashicorp/null" { + version = "3.2.1" + hashes = [ + "h1:ydA0/SNRVB1o95btfshvYsmxA+jZFRZcvKzZSB+4S1M=", + "zh:58ed64389620cc7b82f01332e27723856422820cfd302e304b5f6c3436fb9840", + "zh:62a5cc82c3b2ddef7ef3a6f2fedb7b9b3deff4ab7b414938b08e51d6e8be87cb", + "zh:63cff4de03af983175a7e37e52d4bd89d990be256b16b5c7f919aff5ad485aa5", + "zh:74cb22c6700e48486b7cabefa10b33b801dfcab56f1a6ac9b6624531f3d36ea3", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:79e553aff77f1cfa9012a2218b8238dd672ea5e1b2924775ac9ac24d2a75c238", + "zh:a1e06ddda0b5ac48f7e7c7d59e1ab5a4073bbcf876c73c0299e4610ed53859dc", + "zh:c37a97090f1a82222925d45d84483b2aa702ef7ab66532af6cbcfb567818b970", + "zh:e4453fbebf90c53ca3323a92e7ca0f9961427d2f0ce0d2b65523cc04d5d999c2", + "zh:e80a746921946d8b6761e77305b752ad188da60688cfd2059322875d363be5f5", + "zh:fbdb892d9822ed0e4cb60f2fedbdbb556e4da0d88d3b942ae963ed6ff091e48f", + "zh:fca01a623d90d0cad0843102f9b8b9fe0d3ff8244593bd817f126582b52dd694", + ] +} + provider "registry.terraform.io/hashicorp/random" { version = "3.5.1" constraints = "~> 3.0" diff --git a/examples/multi-runner/README.md b/examples/multi-runner/README.md index d459948799..20378772ae 100644 --- a/examples/multi-runner/README.md +++ b/examples/multi-runner/README.md @@ -39,14 +39,12 @@ terraform init terraform apply ``` -You can receive the webhook details by running: +The module will try to update the GitHub App webhook and secret (only linux/mac). You can receive the webhook details by running: ```bash -terraform output -raw webhook_secret +terraform output webhook_secret ``` -Be aware some shells will print some end of line character `%`. - ## Requirements @@ -69,6 +67,7 @@ Be aware some shells will print some end of line character `%`. |------|--------|---------| | [base](#module\_base) | ../base | n/a | | [multi-runner](#module\_multi-runner) | ../../modules/multi-runner | n/a | +| [webhook-github-app](#module\_webhook-github-app) | ../../modules/webhook-github-app | n/a | ## Resources diff --git a/examples/multi-runner/main.tf b/examples/multi-runner/main.tf index 527142716f..1366c7e7c6 100644 --- a/examples/multi-runner/main.tf +++ b/examples/multi-runner/main.tf @@ -9,6 +9,7 @@ locals { resource "random_id" "random" { byte_length = 20 } + module "base" { source = "../base" @@ -46,3 +47,14 @@ module "multi-runner" { # Enable debug logging for the lambda functions # log_level = "debug" } + +module "webhook-github-app" { + source = "../../modules/webhook-github-app" + + github_app = { + key_base64 = var.github_app.key_base64 + id = var.github_app.id + webhook_secret = random_id.random.hex + } + webhook_endpoint = module.multi-runner.webhook.endpoint +} diff --git a/examples/prebuilt/README.md b/examples/prebuilt/README.md index b3be78f896..71ed53a26d 100644 --- a/examples/prebuilt/README.md +++ b/examples/prebuilt/README.md @@ -86,14 +86,12 @@ terraform init terraform apply ``` -You can receive the webhook details by running: +The module will try to update the GitHub App webhook and secret (only linux/mac). You can receive the webhook details by running: ```bash -terraform output -raw webhook_secret +terraform output webhook_secret ``` -Be aware some shells will print some end of line character `%`. - ## Requirements @@ -117,6 +115,7 @@ Be aware some shells will print some end of line character `%`. |------|--------|---------| | [base](#module\_base) | ../base | n/a | | [runners](#module\_runners) | ../../ | n/a | +| [webhook-github-app](#module\_webhook-github-app) | ../../modules/webhook-github-app | n/a | ## Resources diff --git a/examples/prebuilt/main.tf b/examples/prebuilt/main.tf index 80804cc70f..18c60f3710 100644 --- a/examples/prebuilt/main.tf +++ b/examples/prebuilt/main.tf @@ -61,3 +61,14 @@ module "runners" { # override scaling down scale_down_schedule_expression = "cron(* * * * ? *)" } + +module "webhook-github-app" { + source = "../../modules/webhook-github-app" + + github_app = { + key_base64 = var.github_app.key_base64 + id = var.github_app.id + webhook_secret = random_id.random.hex + } + webhook_endpoint = module.runners.webhook.endpoint +} diff --git a/examples/ubuntu/README.md b/examples/ubuntu/README.md index ae998ee600..1a99439b9d 100644 --- a/examples/ubuntu/README.md +++ b/examples/ubuntu/README.md @@ -23,6 +23,12 @@ terraform init terraform apply ``` +The module will try to update the GitHub App webhook and secret (only linux/mac). You can receive the webhook details by running: + +```bash +terraform output webhook_secret +``` + ## Requirements @@ -45,6 +51,7 @@ terraform apply |------|--------|---------| | [base](#module\_base) | ../base | n/a | | [runners](#module\_runners) | ../../ | n/a | +| [webhook-github-app](#module\_webhook-github-app) | ../../modules/webhook-github-app | n/a | ## Resources @@ -65,4 +72,4 @@ terraform apply | [runners](#output\_runners) | n/a | | [webhook\_endpoint](#output\_webhook\_endpoint) | n/a | | [webhook\_secret](#output\_webhook\_secret) | n/a | - \ No newline at end of file + diff --git a/examples/ubuntu/main.tf b/examples/ubuntu/main.tf index 83ff366c9f..06b9fe6833 100644 --- a/examples/ubuntu/main.tf +++ b/examples/ubuntu/main.tf @@ -111,3 +111,14 @@ module "runners" { # Enable logging all commands of user_data, secrets will be logged!!! # enable_user_data_debug_logging_runner = true } + +module "webhook-github-app" { + source = "../../modules/webhook-github-app" + + github_app = { + key_base64 = var.github_app.key_base64 + id = var.github_app.id + webhook_secret = random_id.random.hex + } + webhook_endpoint = module.runners.webhook.endpoint +} diff --git a/examples/windows/README.md b/examples/windows/README.md index 842906833f..2700e663b5 100644 --- a/examples/windows/README.md +++ b/examples/windows/README.md @@ -25,6 +25,12 @@ terraform apply _**Note**_: It can take upwards of ten minutes for a runner to start processing jobs, and about as long for logs to start showing up. It's recommend that scale the runners via a warm-up job and then keep them idled. +The module will try to update the GitHub App webhook and secret (only linux/mac). You can receive the webhook details by running: + +```bash +terraform output webhook_secret +``` + ## Requirements @@ -47,6 +53,7 @@ _**Note**_: It can take upwards of ten minutes for a runner to start processing |------|--------|---------| | [base](#module\_base) | ../base | n/a | | [runners](#module\_runners) | ../../ | n/a | +| [webhook-github-app](#module\_webhook-github-app) | ../../modules/webhook-github-app | n/a | ## Resources @@ -67,4 +74,4 @@ _**Note**_: It can take upwards of ten minutes for a runner to start processing | [runners](#output\_runners) | n/a | | [webhook\_endpoint](#output\_webhook\_endpoint) | n/a | | [webhook\_secret](#output\_webhook\_secret) | n/a | - \ No newline at end of file + diff --git a/examples/windows/main.tf b/examples/windows/main.tf index fd0716ac3d..25784981eb 100644 --- a/examples/windows/main.tf +++ b/examples/windows/main.tf @@ -53,3 +53,14 @@ module "runners" { # override scaling down for testing scale_down_schedule_expression = "cron(* * * * ? *)" } + +module "webhook-github-app" { + source = "../../modules/webhook-github-app" + + github_app = { + key_base64 = var.github_app.key_base64 + id = var.github_app.id + webhook_secret = random_id.random.hex + } + webhook_endpoint = module.runners.webhook.endpoint +} diff --git a/modules/webhook-github-app/README.md b/modules/webhook-github-app/README.md new file mode 100644 index 0000000000..ba0ca7190d --- /dev/null +++ b/modules/webhook-github-app/README.md @@ -0,0 +1,41 @@ +# Module - Update GitHub App Webhook + +> This module is using the local executor to run a bash script. + +This module updates the GitHub App webhook with the endpoint and secret and can be changed with the root module. See the examples for usages. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.3.0 | +| [null](#requirement\_null) | ~> 3 | + +## Providers + +| Name | Version | +|------|---------| +| [null](#provider\_null) | ~> 3 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [null_resource.update_app](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [github\_app](#input\_github\_app) | GitHub app parameters, see your github app. Ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`). |
object({
key_base64 = string
id = string
webhook_secret = string
})
| n/a | yes | +| [webhook\_endpoint](#input\_webhook\_endpoint) | The endpoint to use for the webhook, defaults to the endpoint of the runners module. | `string` | n/a | yes | + +## Outputs + +No outputs. + diff --git a/modules/webhook-github-app/bin/update-app.sh b/modules/webhook-github-app/bin/update-app.sh new file mode 100755 index 0000000000..0c3d604286 --- /dev/null +++ b/modules/webhook-github-app/bin/update-app.sh @@ -0,0 +1,95 @@ +#!/bin/bash +set -e + +### CHECKS ### + +function testCommand() { + if ! command -v $1 &> /dev/null + then + echo "$1 could not be found" + exit + fi +} + +testCommand gh + +# create usages function usages mesaages. APP_ID and APP_PRIVATE_KEY_PATH are required as parameter or environment variable +usages() { + echo "Description: Update the GitHub App webhook configuration with terraform output for the webhook output of the module." >&2 + echo " " >&2 + echo "Usage: $0" >&2 + echo "Usage: $0 [-h]" >&2 + echo " Use environment variables" >&2 + echo " -a APP_ID GitHub App ID" >&2 + echo " -k APP_PRIVATE_KEY_BASE64 Base64 encoded private key of the GitHub App" >&2 + echo " -f APP APP_PRIVATE_KEY_FILE Path to the private key of the GitHub App" >&2 + echo " -we WEBHOOK_ENDPOINT Webhook endpoint" >&2 + echo " -ws WEBHOOK_SECRET Webhook secret" >&2 + echo " -h Show this help message" >&2 + exit 1 +} + +# hadd h flag to show help +while getopts a:f:k:ws:we:h flag +do + case "${flag}" in + a) APP_ID=${OPTARG};; + f) APP_PRIVATE_KEY_FILE=${OPTARG};; + k) APP_PRIVATE_KEY_BASE64=${OPTARG};; + we) WEBHOOK_ENDPOINT=${OPTARG};; + ws) WEBHOOK_SECRET=${OPTARG};; + h) usages ;; + esac +done + +if [ -z "$APP_ID" ]; then + echo "APP_ID must be set" + usages +fi + +# check one of variables APP_PRIVATE_KEY_PATH or APP_PRIVATE_KEY are set +if [ -z "$APP_PRIVATE_KEY_BASE64" ] && [ -z "$APP_PRIVATE_KEY_FILE" ]; then + echo "APP_PRIVATE_KEY_BASE64 or APP_PRIVATE_KEY_FILE must be set" + usages +fi + +### Terraform outputs ### + +if [ -z "$WEBHOOK_ENDPOINT" ]; then + testCommand terraform + WEBHOOK_ENDPOINT=$(terraform output --raw webhook_endpoint) +fi + +if [ -z "$WEBHOOK_SECRET" ]; then + testCommand terraform + WEBHOOK_SECRET=$(terraform output --raw webhook_secret) +fi + +### CREATE JWT TOKEN ### + +# Generate the JWT header and payload +HEADER=$(echo -n '{"alg":"RS256","typ":"JWT"}' | base64 | tr -d '\n') +PAYLOAD=$(echo -n "{\"iat\":$(date +%s),\"exp\":$(( $(date +%s) + 600 )),\"iss\":$APP_ID}" | base64 | tr -d '\n') + +# Generate the signature +if [ -z "$APP_PRIVATE_KEY_BASE64" ]; then + APP_PRIVATE_KEY_BASE64=$(cat $APP_PRIVATE_KEY_FILE | base64 | tr -d '\n') +fi + +SIGNATURE=$(echo -n "$HEADER.$PAYLOAD" | openssl dgst -sha256 -sign <(echo "$APP_PRIVATE_KEY_BASE64" | base64 -d) | base64 | tr -d '\n') + +JWT_TOKEN="$HEADER.$PAYLOAD.$SIGNATURE" + + +### UPDATE WEBHOOK ### + +gh api \ + --method PATCH \ + -H "Authorization: Bearer ${JWT_TOKEN}" \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /app/hook/config \ + -f content_type='json' \ + -f insecure_ssl='0' \ + -f secret=${WEBHOOK_SECRET} \ + -f url=${WEBHOOK_ENDPOINT} diff --git a/modules/webhook-github-app/main.tf b/modules/webhook-github-app/main.tf new file mode 100644 index 0000000000..5488c58ef2 --- /dev/null +++ b/modules/webhook-github-app/main.tf @@ -0,0 +1,12 @@ +resource "null_resource" "update_app" { + triggers = { + webhook_endpoint = var.webhook_endpoint + webhook_secret = var.github_app.webhook_secret + } + + provisioner "local-exec" { + interpreter = ["bash", "-c"] + command = "${path.module}/bin/update_app.sh -we ${var.webhook_endpoint} -ws ${var.github_app.webhook_secret} -a ${var.github_app.id} -k ${var.github_app.key_base64}" + on_failure = continue + } +} diff --git a/modules/webhook-github-app/variables.tf b/modules/webhook-github-app/variables.tf new file mode 100644 index 0000000000..69d404b7b4 --- /dev/null +++ b/modules/webhook-github-app/variables.tf @@ -0,0 +1,13 @@ +variable "github_app" { + description = "GitHub app parameters, see your github app. Ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`)." + type = object({ + key_base64 = string + id = string + webhook_secret = string + }) +} + +variable "webhook_endpoint" { + description = "The endpoint to use for the webhook, defaults to the endpoint of the runners module." + type = string +} diff --git a/modules/webhook-github-app/versions.tf b/modules/webhook-github-app/versions.tf new file mode 100644 index 0000000000..e0632ba7df --- /dev/null +++ b/modules/webhook-github-app/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.3.0" + + required_providers { + null = { + source = "hashicorp/null" + version = "~> 3" + } + } +}