From 2cfa73c7d7457003df24e78b218e48db183d62d2 Mon Sep 17 00:00:00 2001 From: Nils Date: Sun, 27 Jul 2025 12:49:30 +0200 Subject: [PATCH 01/12] start with volume --- README.md | 15 +++++++++++++++ action.sh | 24 +++++++++++++++++++----- action.yml | 6 ++++++ create-server.template.json | 1 + 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 529eaed..08fbe4e 100644 --- a/README.md +++ b/README.md @@ -162,6 +162,7 @@ jobs: | `server_type` | | Name of the Server type this Server should be created with. | `cx22` (Intel x86, 2 vCPU, 4GB RAM, 40GB SSD) | | `server_wait` | | Wait up to `server_wait` retries (10 sec each) for the Hetzner Cloud Server to start. | `30` (5 min) | | `ssh_key` | | SSH key ID (integer) which should be injected into the Server at creation time. | `null` | +| `volume` | | Volume ID which should be attached to the Server at the creation time. Volume must be in the same Location. | `null` | ## Outputs @@ -291,6 +292,20 @@ hcloud network list --output "columns=ID,NAME,IP_RANGE,SERVERS" hcloud ssh-key list --output "columns=ID,NAME" ``` +**List Volumes:** + +```bash +hcloud volume list --output "columns=ID,NAME,LOCATION" +``` + +**Create Volume:** + +To create a 10GB volume named `volume-test` in the Nuremberg DC Park 1 (`nbg1`) location, use the following command: + +```bash +hcloud volume create --name "volume-test" --size "10" --location "nbg1" +``` + ## Security > We recommend that you only use self-hosted runners with private repositories. diff --git a/action.sh b/action.sh index 7832297..735dc96 100644 --- a/action.sh +++ b/action.sh @@ -226,6 +226,14 @@ if [[ "$MY_SSH_KEY" != "null" && ! "$MY_SSH_KEY" =~ ^[0-9]+$ ]]; then exit_with_failure "The SSH key ID must be 'null' or an integer!" fi +# Set the volume ID which should be attached to the instance at the creation time (default: null) +# If INPUT_VOLUME is set, use its value; otherwise, use "null". +MY_VOLUME=${INPUT_VOLUME:-"null"} +# Check if MY_VOLUME is an integer +if [[ "$MY_VOLUME" != "null" && ! "$MY_VOLUME" =~ ^[0-9]+$ ]]; then + exit_with_failure "The volume ID must be 'null' or an integer!" +fi + # # DELETE # @@ -369,17 +377,23 @@ if [[ "$MY_PRIMARY_IPV6" != "null" ]]; then jq ".public_net.ipv6 = $MY_PRIMARY_IPV6" < create-server-ipv6.json > create-server.json && \ echo "Primary IPv6 ID added to create-server.json." fi +# Add network configuration to the create-server.json file if MY_NETWORK is not "null". +if [[ "$MY_NETWORK" != "null" ]]; then + cp create-server.json create-server-network.json && \ + jq ".networks += [$MY_NETWORK]" < create-server-network.json > create-server.json && \ + echo "Network added to create-server.json." +fi # Add SSH key configuration to the create-server.json file if MY_SSH_KEY is not "null". if [[ "$MY_SSH_KEY" != "null" ]]; then cp create-server.json create-server-ssh.json && \ jq ".ssh_keys += [$MY_SSH_KEY]" < create-server-ssh.json > create-server.json && \ echo "SSH key added to create-server.json." fi -# Add network configuration to the create-server.json file if MY_NETWORK is not "null". -if [[ "$MY_NETWORK" != "null" ]]; then - cp create-server.json create-server-network.json && \ - jq ".networks += [$MY_NETWORK]" < create-server-network.json > create-server.json && \ - echo "Network added to create-server.json." +# Add volume configuration to the create-server.json file if MY_VOLUME is not "null". +if [[ "$MY_VOLUME" != "null" ]]; then + cp create-server.json create-server-volume.json && \ + jq ".volumes += [$MY_VOLUME]" < create-server-volume.json > create-server.json && \ + echo "Volume added to create-server.json." fi # Send a POST request to the Hetzner Cloud API to create a server. diff --git a/action.yml b/action.yml index 5575849..36a364e 100644 --- a/action.yml +++ b/action.yml @@ -112,6 +112,11 @@ inputs: SSH key ID (integer) or name which should be injected into the Server at creation time. required: false default: 'null' + volume: + description: >- + Volume ID (integer) which should be attached to the Server at the creation time. + required: false + default: 'null' outputs: label: @@ -154,3 +159,4 @@ runs: INPUT_SERVER_TYPE: ${{ inputs.server_type }} INPUT_SERVER_WAIT: ${{ inputs.server_wait }} INPUT_SSH_KEY: ${{ inputs.ssh_key }} + INPUT_VOLUME: ${{ inputs.volume }} diff --git a/create-server.template.json b/create-server.template.json index 40646fb..9f4e9aa 100644 --- a/create-server.template.json +++ b/create-server.template.json @@ -17,5 +17,6 @@ }, "start_after_create": true, "ssh_keys": [], + "volumes": [], "user_data": $cloud_init_yml, } From 78bb585ddfe87f15a9dc0feb9d83175ebcd22115 Mon Sep 17 00:00:00 2001 From: Nils Date: Sun, 27 Jul 2025 13:48:38 +0200 Subject: [PATCH 02/12] debug --- action.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/action.sh b/action.sh index 735dc96..314ead6 100644 --- a/action.sh +++ b/action.sh @@ -396,6 +396,9 @@ if [[ "$MY_VOLUME" != "null" ]]; then echo "Volume added to create-server.json." fi +# Temp: Show create-server.json +jq < create-server.json + # Send a POST request to the Hetzner Cloud API to create a server. # https://docs.hetzner.cloud/#servers-create-a-server MAX_RETRIES=$MY_CREATE_WAIT From b00fa18b0f00e6d3afb6d6f4836a0c7c989ba926 Mon Sep 17 00:00:00 2001 From: Nils Date: Sun, 27 Jul 2025 13:55:07 +0200 Subject: [PATCH 03/12] readme fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 08fbe4e..a820164 100644 --- a/README.md +++ b/README.md @@ -162,7 +162,7 @@ jobs: | `server_type` | | Name of the Server type this Server should be created with. | `cx22` (Intel x86, 2 vCPU, 4GB RAM, 40GB SSD) | | `server_wait` | | Wait up to `server_wait` retries (10 sec each) for the Hetzner Cloud Server to start. | `30` (5 min) | | `ssh_key` | | SSH key ID (integer) which should be injected into the Server at creation time. | `null` | -| `volume` | | Volume ID which should be attached to the Server at the creation time. Volume must be in the same Location. | `null` | +| `volume` | | Volume ID (integer) which should be attached to the Server at the creation time. Volume must be in the same Location. | `null` | ## Outputs From 2264283eadbe2dc785d3d5e6a7287e8bf7350d2d Mon Sep 17 00:00:00 2001 From: Nils Date: Sun, 27 Jul 2025 14:16:21 +0200 Subject: [PATCH 04/12] automount --- action.sh | 3 +++ create-server.template.json | 1 + 2 files changed, 4 insertions(+) diff --git a/action.sh b/action.sh index 314ead6..f4767e7 100644 --- a/action.sh +++ b/action.sh @@ -433,6 +433,9 @@ while [[ $RETRY_COUNT -lt $MAX_RETRIES ]]; do sleep "$WAIT_SEC" done +# Temp: Show servers.json +jq < servers.json + # Get the Hetzner Server ID from the JSON response (assuming valid JSON) MY_HETZNER_SERVER_ID=$(jq -er '.server.id' < "servers.json") diff --git a/create-server.template.json b/create-server.template.json index 9f4e9aa..d8e5577 100644 --- a/create-server.template.json +++ b/create-server.template.json @@ -18,5 +18,6 @@ "start_after_create": true, "ssh_keys": [], "volumes": [], + "automount": true, "user_data": $cloud_init_yml, } From 9f7dfdba6adea2f886ac46642391944851f00b17 Mon Sep 17 00:00:00 2001 From: Nils Date: Sun, 27 Jul 2025 14:29:48 +0200 Subject: [PATCH 05/12] json like in example docu --- create-server.template.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/create-server.template.json b/create-server.template.json index d8e5577..588a2f4 100644 --- a/create-server.template.json +++ b/create-server.template.json @@ -1,5 +1,13 @@ { + "name": $name, "location": $location, + "server_type": $server_type, + "start_after_create": true, + "image": $image, + "ssh_keys": [], + "volumes": [], + "networks": [], + "user_data": $cloud_init_yml, "labels": { "type": "github-runner", "os-image": $image, @@ -7,17 +15,9 @@ "gh-owner-id": $github_owner_id, "gh-repo-id": $github_repo_id }, - "image": $image, - "server_type": $server_type, - "name": $name, - "networks": [], + "automount": true, "public_net": { "enable_ipv4": $enable_ipv4, "enable_ipv6": $enable_ipv6, - }, - "start_after_create": true, - "ssh_keys": [], - "volumes": [], - "automount": true, - "user_data": $cloud_init_yml, + } } From f59978fe6fdebf3d9094cbde66be6f42f114d739 Mon Sep 17 00:00:00 2001 From: Nils Date: Sun, 27 Jul 2025 14:34:18 +0200 Subject: [PATCH 06/12] temp output removed --- action.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/action.sh b/action.sh index f4767e7..735dc96 100644 --- a/action.sh +++ b/action.sh @@ -396,9 +396,6 @@ if [[ "$MY_VOLUME" != "null" ]]; then echo "Volume added to create-server.json." fi -# Temp: Show create-server.json -jq < create-server.json - # Send a POST request to the Hetzner Cloud API to create a server. # https://docs.hetzner.cloud/#servers-create-a-server MAX_RETRIES=$MY_CREATE_WAIT @@ -433,9 +430,6 @@ while [[ $RETRY_COUNT -lt $MAX_RETRIES ]]; do sleep "$WAIT_SEC" done -# Temp: Show servers.json -jq < servers.json - # Get the Hetzner Server ID from the JSON response (assuming valid JSON) MY_HETZNER_SERVER_ID=$(jq -er '.server.id' < "servers.json") From 386633a68eee55e13ed4b6865abd7c7cd56c1655 Mon Sep 17 00:00:00 2001 From: Nils Date: Sun, 27 Jul 2025 14:39:02 +0200 Subject: [PATCH 07/12] ext4 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a820164..2e7858a 100644 --- a/README.md +++ b/README.md @@ -303,7 +303,7 @@ hcloud volume list --output "columns=ID,NAME,LOCATION" To create a 10GB volume named `volume-test` in the Nuremberg DC Park 1 (`nbg1`) location, use the following command: ```bash -hcloud volume create --name "volume-test" --size "10" --location "nbg1" +hcloud volume create --name "volume-test" --size "10" --format "ext4" --location "nbg1" ``` ## Security From 89d81c6016fe60c70d8799146ab49ffa55b26ab1 Mon Sep 17 00:00:00 2001 From: Nils Date: Wed, 13 Aug 2025 11:36:23 +0200 Subject: [PATCH 08/12] debug automount --- action.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/action.sh b/action.sh index 735dc96..4076c46 100644 --- a/action.sh +++ b/action.sh @@ -430,6 +430,11 @@ while [[ $RETRY_COUNT -lt $MAX_RETRIES ]]; do sleep "$WAIT_SEC" done +# TODO: Remove after test +# Temp: Show servers.json +jq < create-server.json +jq < servers.json + # Get the Hetzner Server ID from the JSON response (assuming valid JSON) MY_HETZNER_SERVER_ID=$(jq -er '.server.id' < "servers.json") From 21a3012d8d6e601785dbb957ed5a59a70ea02b7b Mon Sep 17 00:00:00 2001 From: Nils Date: Wed, 13 Aug 2025 11:53:23 +0200 Subject: [PATCH 09/12] automount false --- create-server.template.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/create-server.template.json b/create-server.template.json index 588a2f4..452b822 100644 --- a/create-server.template.json +++ b/create-server.template.json @@ -15,7 +15,7 @@ "gh-owner-id": $github_owner_id, "gh-repo-id": $github_repo_id }, - "automount": true, + "automount": false, "public_net": { "enable_ipv4": $enable_ipv4, "enable_ipv6": $enable_ipv6, From 32f554fa9b52c40da5a3472094bcf3633b74b7dc Mon Sep 17 00:00:00 2001 From: Nils Date: Thu, 14 Aug 2025 14:36:02 +0200 Subject: [PATCH 10/12] udevadm --- cloud-init.template.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/cloud-init.template.yml b/cloud-init.template.yml index 13ec383..01d0971 100644 --- a/cloud-init.template.yml +++ b/cloud-init.template.yml @@ -8,6 +8,7 @@ packages: package_update: true package_upgrade: false runcmd: + - udevadm trigger -c add -s block -p ID_VENDOR=HC -p ID_MODEL=Volume - export RUNNER_ALLOW_RUNASROOT=1 - bash $MY_RUNNER_DIR/pre_runner_script.sh - bash $MY_RUNNER_DIR/install.sh -v "$MY_RUNNER_VERSION" -d "$MY_RUNNER_DIR" From e9a66e08f9d44843083265c00a45c7ea9dc154ef Mon Sep 17 00:00:00 2001 From: Nils Date: Thu, 14 Aug 2025 14:55:06 +0200 Subject: [PATCH 11/12] optimized readme --- README.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 2e7858a..aeafe94 100644 --- a/README.md +++ b/README.md @@ -162,7 +162,7 @@ jobs: | `server_type` | | Name of the Server type this Server should be created with. | `cx22` (Intel x86, 2 vCPU, 4GB RAM, 40GB SSD) | | `server_wait` | | Wait up to `server_wait` retries (10 sec each) for the Hetzner Cloud Server to start. | `30` (5 min) | | `ssh_key` | | SSH key ID (integer) which should be injected into the Server at creation time. | `null` | -| `volume` | | Volume ID (integer) which should be attached to the Server at the creation time. Volume must be in the same Location. | `null` | +| `volume` | | Specify a Volume ID (integer) to attach and mount to the Server during creation. The volume will be automatically mounted at `/mnt/HC_Volume_[VOLUME-ID]`. The volume must be in the same location as the Server. More details in [Volumes section](#Volumes). | `null` | ## Outputs @@ -175,6 +175,8 @@ jobs: The following `hcloud` CLI commands can help you find the required input values. +### Locations + **List Locations:** ```bash @@ -191,6 +193,8 @@ nbg1 Nuremberg DC Park 1 eu-central DE Nuremberg sin Singapore ap-southeast SG Singapore ``` +### Server Types + **List Server Types:** ```bash @@ -220,6 +224,8 @@ cx42 8 shared x86 16.0 GB 160 GB cx52 16 shared x86 32.0 GB 320 GB ``` +### Images + **List x86_64 Images:** ```bash @@ -274,24 +280,30 @@ Tip: Create custom images with HashiCorp [Packer](https://github.com/hetznerclou hcloud image list --output "columns=ID,DESCRIPTION,ARCHITECTURE,DISK_SIZE" --type "snapshot" --sort "name" ``` -**List Primary IPs:** +### Network + +**List Networks:** ```bash -hcloud primary-ip list --output "columns=ID,TYPE,NAME,IP,ASSIGNEE" +hcloud network list --output "columns=ID,NAME,IP_RANGE,SERVERS" ``` -**List Networks:** +**List Primary IPs:** ```bash -hcloud network list --output "columns=ID,NAME,IP_RANGE,SERVERS" +hcloud primary-ip list --output "columns=ID,TYPE,NAME,IP,ASSIGNEE" ``` +### SSH + **List SSH Keys:** ```bash hcloud ssh-key list --output "columns=ID,NAME" ``` +### Volumes + **List Volumes:** ```bash From 489ccbb300be3310365741e073a6401f32375c1c Mon Sep 17 00:00:00 2001 From: Nils Date: Thu, 14 Aug 2025 14:55:25 +0200 Subject: [PATCH 12/12] debug removed --- action.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/action.sh b/action.sh index 4076c46..735dc96 100644 --- a/action.sh +++ b/action.sh @@ -430,11 +430,6 @@ while [[ $RETRY_COUNT -lt $MAX_RETRIES ]]; do sleep "$WAIT_SEC" done -# TODO: Remove after test -# Temp: Show servers.json -jq < create-server.json -jq < servers.json - # Get the Hetzner Server ID from the JSON response (assuming valid JSON) MY_HETZNER_SERVER_ID=$(jq -er '.server.id' < "servers.json")