Schedule icon
Commands icon
Docker icon
Script icon
Process icon
If icon
Create icon
SlackIncomingWebhook icon
Log icon

Domain Registration Expiry and Renewal Guard

Watch domain registration expiry with Kestra. Run whois per domain, score days left against 90 and 30 day thresholds, escalate renewals to GitHub and Slack.

Categories
Infrastructure

Domain names lapse quietly. When a registration is not renewed the domain stops resolving, the registrar can resell it, and the cheapest fix becomes a brokerage or legal fight instead of a renewal fee. This flow runs a whois sweep over your domain list on a schedule, scores every registration against a warn and a critical day threshold, and turns anything close to expiry into a GitHub renewal ticket plus a Slack alert. It watches the registration date that the registry publishes over whois, which is a different asset from the validity window of a TLS certificate, so certificate monitoring stays a separate concern.

How it works

  1. The weekly_expiry_sweep trigger (io.kestra.plugin.core.trigger.Schedule, cron 0 6 * * 1, shipped with disabled: true) starts the sweep every Monday morning once you enable it.
  2. lookup_registrations (io.kestra.plugin.scripts.shell.Commands on the io.kestra.plugin.scripts.runner.docker.Docker runner, image alpine:3.20) installs the whois client and loops over the comma separated domains input, printing a ### DOMAIN <name> marker followed by the raw whois text for each registration.
  3. assess_expiry (io.kestra.plugin.scripts.python.Script) receives that text together with warn_days, critical_days, and today's date through environment variables, pulls the expiry date out of each block, and computes days remaining per domain.
  4. Every domain lands in critical, warn, ok, or unknown, where unknown means the whois text carried no parseable expiry date, and the task emits the whole verdict through the ::json:: outputs protocol.
  5. route_verdict (io.kestra.plugin.core.flow.If) branches when the verdict is anything other than ok. Inside the branch, open_renewal_issue (io.kestra.plugin.github.issues.Create) files a ticket whose body lists every domain sorted by urgency, and alert_slack posts the same summary to Slack, while a clean sweep falls through to all_clear_note (io.kestra.plugin.core.log.Log).
  6. The errors handler reports any crash to Slack, so a container that never started is never mistaken for a healthy portfolio.

What you get

  • Four flow outputs, verdict, critical_domains, warn_domains, and nearest_expiry, ready for a downstream flow to branch on.
  • Days remaining and the exact expiry date for every domain, with severity attached to each record.
  • A GitHub issue that lists the whole portfolio in urgency order, critical domains first and the nearest expiry at the top.
  • A Slack message carrying the same summary, so the channel sees the count and the closest deadline without opening the ticket.
  • An execution history that records every sweep, which turns "did anyone check the renewals this month" into an answerable question.
  • Thresholds as inputs, so a team that wants 60 and 14 days changes two numbers instead of editing a script.

Who it's for

  • Teams that own a portfolio of brand, product, and campaign domains across one or more registrars.
  • Agencies responsible for client renewals who need the deadline visible in the same backlog as their other ops work.
  • Platform and DNS owners who want expiring registrations surfaced on a cadence instead of discovered during an outage.
  • Anyone who has already lost a domain to a missed renewal and wants the check to be automatic and auditable.

Why orchestrate this with Kestra

A whois client returns text and nothing else, so the usual answer is a cron job writing to a file that nobody reads until the domain is gone. Kestra gives that lookup a schedule, hermetic tooling through a container runner, thresholds as typed inputs, a branch that separates escalation from the all clear, and an execution record for every run. The escalation itself is declarative too, the GitHub issue and the Slack message come from the same file that defines the check, and the errors handler catches failures in the guard itself. Change the thresholds or the domain list in a pull request and the review history shows exactly when the policy moved.

Prerequisites

  • A Kestra worker with Docker access, since the whois lookup runs inside the alpine:3.20 container.
  • Outbound network access from that worker to the registry whois servers on TCP port 43.
  • A GitHub repository where the provided token is allowed to open issues.
  • A Slack incoming webhook for the alert and the failure notification.
  • Python 3 available on the worker for the assessment step, or switch it to a Docker task runner.

Secrets

  • GITHUB_TOKEN: token passed to jwtToken for opening the renewal issue.
  • SLACK_WEBHOOK_URL: Slack incoming webhook URL used by the alert and the errors handler.

Quick start

  1. Add the two secrets above to your Kestra namespace.
  2. Replace the domains input default with your own comma separated list and confirm warn_days and critical_days.
  3. Set repository on the open_renewal_issue task to the backlog where renewal tickets should land.
  4. Run the flow once by hand and read the verdict, critical_domains, and nearest_expiry outputs before trusting the branch.
  5. Enable the weekly sweep by flipping the trigger, for example:
triggers:
  - id: weekly_expiry_sweep
    type: io.kestra.plugin.core.trigger.Schedule
    cron: "0 6 * * 1"
    disabled: false

How to extend

  • Grow the list by overriding the domains input per call, or read a maintained list from a KV store or a namespace file and feed it to the lookup step.
  • Retune warn_days and critical_days per portfolio, for example 60 and 14 for campaign domains that are bought and dropped often.
  • Add io.kestra.plugin.core.execution.Fail after alert_slack when a critical domain should turn the execution red for downstream gates.
  • Fan the alert out to email or a subflow by adding a task next to alert_slack in the same branch.
  • Pair this flow with a TLS certificate monitor, since certificate expiry and registration expiry are different dates and both take a domain down.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.