From 5313a4daea66cf82d4e8fb0b0a37483d2b436076 Mon Sep 17 00:00:00 2001 From: Ivanmeneges Date: Wed, 17 Jun 2026 18:49:17 +0530 Subject: [PATCH 1/7] [Fixes: mosip/mosip-infra#1874] Add WireGuard onboarding workflow in master This workflow automates the onboarding of WireGuard environments by allocating peers and publishing them as GitHub environment secrets. It includes steps for SSH key handling and committing peer allocations if changes occur. Signed-off-by: Ivanmeneges --- .github/workflows/wg-onboard.yml | 113 +++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 .github/workflows/wg-onboard.yml diff --git a/.github/workflows/wg-onboard.yml b/.github/workflows/wg-onboard.yml new file mode 100644 index 00000000..93f369cc --- /dev/null +++ b/.github/workflows/wg-onboard.yml @@ -0,0 +1,113 @@ +name: WireGuard onboard environment + +# Self-service WireGuard onboarding for a new environment. +# Allocates free WireGuard peers from the jumpserver and publishes them as +# GitHub *environment* secrets (TF_WG_CONFIG, CLUSTER_WIREGUARD_WG0/WG1) so a +# QA/dev team can run the Terraform + Helmsman workflows without DevOps. +# +# Requires .github/scripts/wg-onboard.sh (mosip/infra PR #247). + +on: + workflow_dispatch: + inputs: + ENV_NAME: + description: 'Environment / branch name to onboard (becomes the GitHub environment name)' + required: true + type: string + JUMPSERVER_HOST: + description: 'Jumpserver / WireGuard VM public IP or DNS (SSH reachable)' + required: true + type: string + MOSIP_AWS_PEM: + description: 'Name of the repo secret holding the jumpserver SSH private key' + required: true + type: choice + options: + - MOSIP_AWS_PEM + default: MOSIP_AWS_PEM + TICKET: + description: 'Optional ticket id to record in assigned.txt (e.g. DSD-10264)' + required: false + type: string + WG_DIR: + description: 'WireGuard env dir on the VM' + required: false + type: string + default: /home/ubuntu/wireguard_env_2026 + ALLOWED_IPS: + description: 'AllowedIPs to set in each conf' + required: false + type: string + default: 172.31.0.0/16 + DRY_RUN: + description: 'Resolve and print actions without creating env/secrets' + required: false + type: boolean + default: true + +jobs: + onboard: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + token: ${{ secrets.ACTION_PAT }} + persist-credentials: false + + - name: Write SSH private key + env: + SSH_KEY: ${{ secrets.MOSIP_AWS_PEM }} + SSH_KEY_NAME: MOSIP_AWS_PEM + run: | + mkdir -p ~/.ssh + # Use printf + strip CR so multi-line PEMs / CRLF secrets are written intact + printf '%s\n' "$SSH_KEY" | tr -d '\r' > ~/.ssh/jumpserver_key + chmod 600 ~/.ssh/jumpserver_key + if ! ssh-keygen -l -f ~/.ssh/jumpserver_key >/dev/null 2>&1; then + echo "ERROR: secret '$SSH_KEY_NAME' is not a valid private key (check format/newlines/CRLF)" + exit 1 + fi + - name: Run WireGuard onboarding + env: + GH_TOKEN: ${{ secrets.ACTION_PAT }} + GITHUB_TOKEN: ${{ secrets.ACTION_PAT }} + INPUT_ENV_NAME: ${{ inputs.ENV_NAME }} + INPUT_JUMPSERVER_HOST: ${{ inputs.JUMPSERVER_HOST }} + INPUT_WG_DIR: ${{ inputs.WG_DIR }} + INPUT_ALLOWED_IPS: ${{ inputs.ALLOWED_IPS }} + INPUT_TICKET: ${{ inputs.TICKET }} + INPUT_DRY_RUN: ${{ inputs.DRY_RUN }} + GITHUB_REPOSITORY: ${{ github.repository }} + run: | + chmod +x .github/workflows/scripts/wg-onboard.sh + args=( + --env "$INPUT_ENV_NAME" + --host "$INPUT_JUMPSERVER_HOST" + --ssh-key ~/.ssh/jumpserver_key + --repo "$GITHUB_REPOSITORY" + --wg-dir "$INPUT_WG_DIR" + --allowed-ips "$INPUT_ALLOWED_IPS" + ) + [[ -n "$INPUT_TICKET" ]] && args+=(--ticket "$INPUT_TICKET") + [[ "$INPUT_DRY_RUN" == "true" ]] && args+=(--dry-run) + .github/scripts/wg-onboard.sh "${args[@]}" + - name: Commit updated peer allocation + if: ${{ inputs.DRY_RUN == false }} + env: + GH_TOKEN: ${{ secrets.ACTION_PAT }} + INPUT_ENV_NAME: ${{ inputs.ENV_NAME }} + GIT_AUTHOR_NAME: ${{ github.actor }} + GIT_AUTHOR_EMAIL: ${{ github.actor }}@users.noreply.github.com + GIT_COMMITTER_NAME: ${{ github.actor }} + GIT_COMMITTER_EMAIL: ${{ github.actor }}@users.noreply.github.com + run: | + tracker=".github/scripts/wg-peer-allocation.tsv" + if git diff --quiet -- "$tracker"; then + echo "No allocation change to commit" + else + git add "$tracker" + git commit -s -m "wg: allocate peers for environment $INPUT_ENV_NAME" + git pull --rebase origin "${GITHUB_REF_NAME}" + git push "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" "HEAD:${GITHUB_REF_NAME}" + fi From f9784cc52b659ffe453ba817d2327c88c9657ddd Mon Sep 17 00:00:00 2001 From: Ivanmeneges Date: Wed, 17 Jun 2026 18:59:47 +0530 Subject: [PATCH 2/7] Change runner from ubuntu-latest to self-hosted Signed-off-by: Ivanmeneges --- .github/workflows/wg-onboard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/wg-onboard.yml b/.github/workflows/wg-onboard.yml index 93f369cc..fe6aa651 100644 --- a/.github/workflows/wg-onboard.yml +++ b/.github/workflows/wg-onboard.yml @@ -47,7 +47,7 @@ on: jobs: onboard: - runs-on: ubuntu-latest + runs-on: self-hosted steps: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 From 47cdbbc8121bcab2304cbd58b44948ade1573ebe Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 18 Jun 2026 17:58:47 +0530 Subject: [PATCH 3/7] Address CodeRabbit and CodeQL review feedback for wg-onboard workflow. Add explicit permissions, fix script chmod path, store SSH key in RUNNER_TEMP with always-on cleanup, and update script PR reference. Co-authored-by: Cursor --- .github/workflows/wg-onboard.yml | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/.github/workflows/wg-onboard.yml b/.github/workflows/wg-onboard.yml index fe6aa651..25c47b7b 100644 --- a/.github/workflows/wg-onboard.yml +++ b/.github/workflows/wg-onboard.yml @@ -5,7 +5,7 @@ name: WireGuard onboard environment # GitHub *environment* secrets (TF_WG_CONFIG, CLUSTER_WIREGUARD_WG0/WG1) so a # QA/dev team can run the Terraform + Helmsman workflows without DevOps. # -# Requires .github/scripts/wg-onboard.sh (mosip/infra PR #247). +# Requires .github/scripts/wg-onboard.sh (mosip/infra PR #253). on: workflow_dispatch: @@ -45,6 +45,9 @@ on: type: boolean default: true +permissions: + contents: read + jobs: onboard: runs-on: self-hosted @@ -60,14 +63,15 @@ jobs: SSH_KEY: ${{ secrets.MOSIP_AWS_PEM }} SSH_KEY_NAME: MOSIP_AWS_PEM run: | - mkdir -p ~/.ssh - # Use printf + strip CR so multi-line PEMs / CRLF secrets are written intact - printf '%s\n' "$SSH_KEY" | tr -d '\r' > ~/.ssh/jumpserver_key - chmod 600 ~/.ssh/jumpserver_key - if ! ssh-keygen -l -f ~/.ssh/jumpserver_key >/dev/null 2>&1; then + SSH_KEY_PATH="${RUNNER_TEMP}/jumpserver_key" + printf '%s\n' "$SSH_KEY" | tr -d '\r' > "$SSH_KEY_PATH" + chmod 600 "$SSH_KEY_PATH" + if ! ssh-keygen -l -f "$SSH_KEY_PATH" >/dev/null 2>&1; then echo "ERROR: secret '$SSH_KEY_NAME' is not a valid private key (check format/newlines/CRLF)" exit 1 fi + echo "SSH_KEY_PATH=$SSH_KEY_PATH" >> "$GITHUB_ENV" + - name: Run WireGuard onboarding env: GH_TOKEN: ${{ secrets.ACTION_PAT }} @@ -80,11 +84,11 @@ jobs: INPUT_DRY_RUN: ${{ inputs.DRY_RUN }} GITHUB_REPOSITORY: ${{ github.repository }} run: | - chmod +x .github/workflows/scripts/wg-onboard.sh + chmod +x .github/scripts/wg-onboard.sh args=( --env "$INPUT_ENV_NAME" --host "$INPUT_JUMPSERVER_HOST" - --ssh-key ~/.ssh/jumpserver_key + --ssh-key "$SSH_KEY_PATH" --repo "$GITHUB_REPOSITORY" --wg-dir "$INPUT_WG_DIR" --allowed-ips "$INPUT_ALLOWED_IPS" @@ -92,6 +96,11 @@ jobs: [[ -n "$INPUT_TICKET" ]] && args+=(--ticket "$INPUT_TICKET") [[ "$INPUT_DRY_RUN" == "true" ]] && args+=(--dry-run) .github/scripts/wg-onboard.sh "${args[@]}" + + - name: Cleanup SSH private key + if: always() + run: rm -f "${SSH_KEY_PATH:-}" + - name: Commit updated peer allocation if: ${{ inputs.DRY_RUN == false }} env: From 6b4e14082f98977aa9b02b2690ac133738d77dc0 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 18 Jun 2026 20:32:20 +0530 Subject: [PATCH 4/7] wg-onboard: concurrency, pull-before-commit, drop dead input Serialize runs per ENV_NAME, rebase before tracker commit to avoid push conflicts, remove unused MOSIP_AWS_PEM workflow input, and cap job at 20m. Co-authored-by: Cursor --- .github/workflows/wg-onboard.yml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/.github/workflows/wg-onboard.yml b/.github/workflows/wg-onboard.yml index 25c47b7b..65142ede 100644 --- a/.github/workflows/wg-onboard.yml +++ b/.github/workflows/wg-onboard.yml @@ -18,13 +18,6 @@ on: description: 'Jumpserver / WireGuard VM public IP or DNS (SSH reachable)' required: true type: string - MOSIP_AWS_PEM: - description: 'Name of the repo secret holding the jumpserver SSH private key' - required: true - type: choice - options: - - MOSIP_AWS_PEM - default: MOSIP_AWS_PEM TICKET: description: 'Optional ticket id to record in assigned.txt (e.g. DSD-10264)' required: false @@ -48,9 +41,14 @@ on: permissions: contents: read +concurrency: + group: wg-onboard-${{ inputs.ENV_NAME }} + cancel-in-progress: false + jobs: onboard: runs-on: self-hosted + timeout-minutes: 20 steps: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -112,11 +110,11 @@ jobs: GIT_COMMITTER_EMAIL: ${{ github.actor }}@users.noreply.github.com run: | tracker=".github/scripts/wg-peer-allocation.tsv" + git pull --rebase origin "${GITHUB_REF_NAME}" if git diff --quiet -- "$tracker"; then echo "No allocation change to commit" else git add "$tracker" git commit -s -m "wg: allocate peers for environment $INPUT_ENV_NAME" - git pull --rebase origin "${GITHUB_REF_NAME}" git push "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" "HEAD:${GITHUB_REF_NAME}" fi From 3b341eb6a74205c7925ffdbb4624838e251a557d Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 18 Jun 2026 23:34:01 +0530 Subject: [PATCH 5/7] wg-onboard: rebase with autostash only when tracker changed Pull after diff check so dirty-tree rebase errors are avoided; autostash preserves script-written tracker edits and fail fast on conflict. Co-authored-by: Cursor --- .github/workflows/wg-onboard.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/wg-onboard.yml b/.github/workflows/wg-onboard.yml index 65142ede..8a16dbb2 100644 --- a/.github/workflows/wg-onboard.yml +++ b/.github/workflows/wg-onboard.yml @@ -110,10 +110,13 @@ jobs: GIT_COMMITTER_EMAIL: ${{ github.actor }}@users.noreply.github.com run: | tracker=".github/scripts/wg-peer-allocation.tsv" - git pull --rebase origin "${GITHUB_REF_NAME}" if git diff --quiet -- "$tracker"; then echo "No allocation change to commit" else + if ! git pull --rebase --autostash origin "${GITHUB_REF_NAME}"; then + echo "ERROR: Rebase failed (concurrent tracker update?). Resolve on ${GITHUB_REF_NAME} and re-run." + exit 1 + fi git add "$tracker" git commit -s -m "wg: allocate peers for environment $INPUT_ENV_NAME" git push "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" "HEAD:${GITHUB_REF_NAME}" From d78b5a6d98b0a2c2a2733efefddffe593756a098 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 18 Jun 2026 23:39:21 +0530 Subject: [PATCH 6/7] wg-onboard: use GITHUB_TOKEN for checkout, validate secrets early Checkout no longer requires ACTION_PAT (empty secret caused checkout to fail); onboarding still needs ACTION_PAT and MOSIP_AWS_PEM with a clear error when either is missing. Co-authored-by: Cursor --- .github/workflows/wg-onboard.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/wg-onboard.yml b/.github/workflows/wg-onboard.yml index 8a16dbb2..ca3efe0f 100644 --- a/.github/workflows/wg-onboard.yml +++ b/.github/workflows/wg-onboard.yml @@ -50,10 +50,20 @@ jobs: runs-on: self-hosted timeout-minutes: 20 steps: + - name: Validate required secrets + run: | + missing=() + [[ -z "${{ secrets.ACTION_PAT }}" ]] && missing+=(ACTION_PAT) + [[ -z "${{ secrets.MOSIP_AWS_PEM }}" ]] && missing+=(MOSIP_AWS_PEM) + if ((${#missing[@]})); then + echo "ERROR: Missing repository secrets: ${missing[*]}" + echo "Add them under Settings → Secrets and variables → Actions for ${GITHUB_REPOSITORY}" + exit 1 + fi + - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: - token: ${{ secrets.ACTION_PAT }} persist-credentials: false - name: Write SSH private key From 4cfd8abc35b9bdeac1f99f5435506cffdeef6879 Mon Sep 17 00:00:00 2001 From: Ivanmeneges Date: Fri, 19 Jun 2026 13:34:58 +0530 Subject: [PATCH 7/7] Update git pull and push commands with remote URL Signed-off-by: Ivanmeneges --- .github/workflows/wg-onboard.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/wg-onboard.yml b/.github/workflows/wg-onboard.yml index ca3efe0f..79215fd3 100644 --- a/.github/workflows/wg-onboard.yml +++ b/.github/workflows/wg-onboard.yml @@ -123,11 +123,12 @@ jobs: if git diff --quiet -- "$tracker"; then echo "No allocation change to commit" else - if ! git pull --rebase --autostash origin "${GITHUB_REF_NAME}"; then + remote_url="https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" + if ! git pull --rebase --autostash "$remote_url" "${GITHUB_REF_NAME}"; then echo "ERROR: Rebase failed (concurrent tracker update?). Resolve on ${GITHUB_REF_NAME} and re-run." exit 1 fi git add "$tracker" git commit -s -m "wg: allocate peers for environment $INPUT_ENV_NAME" - git push "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" "HEAD:${GITHUB_REF_NAME}" + git push "$remote_url" "HEAD:${GITHUB_REF_NAME}" fi