feat(ci_ephemeral_provisioner): alert before the Tailscale auth key expires #24

Merged
jfraeys merged 2 commits from jfraeys/feat/authkey-expiry-alert into main 2026-10-08 20:22:03 -04:00 AGit
Owner

Stacked on #23 (fix/deploy-services-authkey-env): merge that first, or this PR also shows its commits. deploy-services.sh records the key expiry (CI_EPHEMERAL_TAILSCALE_AUTHKEY_EXPIRES_AT, Unix seconds) when it mints a key; the role writes it as a node-exporter textfile metric (skipped when unset so a known value is never blanked, malformed values fail the play); Prometheus warns 48h before expiry (CIEphemeralAuthKeyExpiringSoon) and goes critical once expired (CIEphemeralAuthKeyExpired), via the existing Alertmanager email route. After merging, deploy the role and Prometheus with the current key expiry exported (conservatively 1792101600, 2026-10-15 22:00Z). Tested: stubbed script runs, rendered alert YAML, local Ansible run of the assert and metric task; PromQL not run through promtool (not installed), not deployed. -- Generated with Claude Code

Stacked on #23 (fix/deploy-services-authkey-env): merge that first, or this PR also shows its commits. deploy-services.sh records the key expiry (CI_EPHEMERAL_TAILSCALE_AUTHKEY_EXPIRES_AT, Unix seconds) when it mints a key; the role writes it as a node-exporter textfile metric (skipped when unset so a known value is never blanked, malformed values fail the play); Prometheus warns 48h before expiry (CIEphemeralAuthKeyExpiringSoon) and goes critical once expired (CIEphemeralAuthKeyExpired), via the existing Alertmanager email route. After merging, deploy the role and Prometheus with the current key expiry exported (conservatively 1792101600, 2026-10-15 22:00Z). Tested: stubbed script runs, rendered alert YAML, local Ansible run of the assert and metric task; PromQL not run through promtool (not installed), not deployed. -- Generated with [Claude Code](https://claude.com/claude-code)
The script sourced .env after the caller's exports, so a stale
CI_EPHEMERAL_TAILSCALE_AUTHKEY line there overrode a freshly minted key and
the deploy kept writing the expired one. Snapshot the caller's
CI_EPHEMERAL_TAILSCALE_AUTHKEY / FORGEJO_RUNNER_APP_SKELETON_DEPLOY_KEY,
drop whatever .env or vault set for them (with a warning), then restore the
caller's. The self-minted key now lasts 168h instead of 4h: the provisioner
reuses it for every VM cycle until the next deploy.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The install task wrote the exported key unconditionally, so a deploy run
without FORGEJO_RUNNER_APP_SKELETON_DEPLOY_KEY replaced the installed key
with an empty file. force is now true only when a key was supplied; the file
is still created when absent because the provisioner script opens it every
cycle.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
docs(ci_ephemeral_provisioner): note why the deploy key task uses force, not when
All checks were successful
Lint / lint (pull_request) Successful in 1m22s
52126669c7
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
deploy-services.sh records the key's expiry when it mints one
(CI_EPHEMERAL_TAILSCALE_AUTHKEY_EXPIRES_AT, Unix seconds); the role writes it
as a node-exporter textfile metric, and Prometheus warns 48h before expiry
and goes critical once expired, reaching the existing Alertmanager email
route. A deploy without an expiry leaves the last known metric in place; a
malformed value fails the play.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
docs(ci_ephemeral_provisioner): drop the wrong history from the app-skeleton deploy key comment
All checks were successful
Lint / lint (pull_request) Successful in 1m17s
abcb33f04c
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jfraeys/infra!24
No description provided.