← All notes
Operations

Your only DevOps engineer just resigned

The notice period is the last time that knowledge is free. Here is what to do with the thirty days you still have.

26 Aug 2026 15 min EN · ES

This note is not a hiring post. It is a triage plan for the first week after the resignation, written as if the person had already left. Because in practice they already have: mentally they are in the next job, and every day that passes the cost of extracting what they know goes up.

If you run a 15–60 person company and your only infrastructure person just handed in notice, you do not need a replacement this week. You need that, within thirty days, the rest of the team can deploy, rotate a key and restore a backup without calling anybody on WhatsApp.

Day 0 — the freeze

The first impulse is to use “while they are still here”: migrate to that new vendor, bump the major Kubernetes version, rewrite the pipeline “properly for once”. It is the most expensive impulse of the thirty days. Every new change is new knowledge that has to be handed over on top of the old knowledge you have not extracted yet.

What you stop the same day:

The one thing you start the same day: recording. Every handover session on video, screen shared, stored where the team can find it without asking permission. A Confluence page written from memory at two in the afternoon does not replace watching the person open the console, hesitate and correct themselves.

The Day 0 rule, said out loud in the first meeting: “During the notice period we do not improve the system. We make it transferable.”

The inventory nobody has

Everybody remembers the servers. Nobody remembers the rest. The inventory that matters is not the instance list: it is the list of logins, invoices and rituals that only fit in one person’s head. If you want the map of what the cluster actually does, not what the diagram says, start with the cluster you can explain.

The short list we ask for on day 1, with an owner and a screenshot that somebody else can get in:

If an item on that list does not have a second human with verified access by Friday of week 1, that item is the month-3 incident.

Week 1 — credentials before knowledge

The classic handover mistake is to start with architecture. Start with the keys. Most teams discover the outage here, by rotating a key and watching the deploy die, rather than in month 3, when the person no longer picks up the phone.

  1. Inventory every human identity with console access or an access key.
  2. Rotate long-lived keys. Federate what you can (OIDC from CI, SSO for humans).
  3. Prove, on the same day as the rotation, that somebody who is not the leaver can still deploy.
  4. Remove the leaver from privileged groups only after that proof, not before.

The proof is not “the pipeline is green”. The proof is: another person merges a trivial change, the pipeline uses the new credentials, and production reflects the change. If that fails, you have found the real bus factor. Better now.

Week 2 — one deploy, done by somebody else

The whole week fits in one rule: somebody on the team deploys a real service to production, with the leaver watching and not typing. Not “I do it and you watch”. Not “we share the keyboard”. The leaver talks. The other person types.

If the path from commit to production still does not fit on a whiteboard, this is the week you reduce it to that, you do not redesign it. The long version of that path is in one path to production: one artifact, promotion by digest, a rehearsed rollback.

By the end of week 2 you want three proofs, not a document:

If by Friday that has not happened, week 3 does not fix the problem: it documents it. For a handover, documenting a path nobody has walked is theatre.

Week 3 — the four runbooks that matter

You do not need the full wiki. You need four procedures somebody on the team can run at three in the morning without inventing. Everything else can be rediscovered; these four cannot, not in time.

  1. Deploy: from merged commit to production traffic, with the checks that matter and the owner of each gate.
  2. Rollback: one command, the previous known-good digest, and what a rollback does not fix (migrations, queued messages, flags).
  3. Restore from backup: where the backup lives, how you verify it is not empty, how long it takes, and who authorises a production restore.
  4. “The site is down and I do not know why”: the five dashboards, the three log queries, the feature-flag kill switch, and the DNS or CDN vendor number.

Each runbook is written while it is executed, not afterwards. If while writing it you discover a step that only exists in the leaver’s head, that step is the afternoon’s work, not a margin note.

Week 4 — what you deliberately do not fix

The temptation of the last week is to rewrite. Naming the debt you choose to keep is how you stop the panic and the “while we are at it”. You make an explicit list, signed by whoever stays in charge:

A list of chosen debt is a plan. A list of denied debt is the month-4 incident, when the new hire arrives to an undocumented mess and assumes the silence was quality.

Artifact: a bus-factor audit

Before you negotiate priorities, pull the numbers. Three blocks, copy-paste. Adapt the cloud; the rest works anywhere.

1. Single-committer services

# from a checkout that contains your service repos as subdirs
for d in */; do
  [ -d "$d/.git" ] || continue
  echo "=== $d ==="
  git -C "$d" shortlog -sne --all | head -5
  authors=$(git -C "$d" shortlog -sne --all | wc -l)
  top=$(git -C "$d" shortlog -sne --all | head -1 | awk '{print $1}')
  total=$(git -C "$d" rev-list --count --all 2>/dev/null || echo 0)
  if [ "$authors" -le 2 ] && [ "$total" -gt 20 ]; then
    echo "BUS FACTOR RISK: ≤2 authors, $total commits, top author ~$top commits"
  fi
done

2. Humans with console access and access-key age

# ── AWS ──
aws iam get-account-authorization-details --output json \
  | jq -r '
    .UserDetailList[]
    | select(.UserName | test("(?i)service|bot|ci") | not)
    | . as $u
    | ($u.AttachedManagedPolicies + ($u.UserPolicyList // [])) as $pols
    | ($u.AccessKeys // [])[]?
    | [$u.UserName, .AccessKeyId, .Status, .CreateDate]
    | @tsv
  '
# console users (password last used is a proxy for "still human")
aws iam generate-credential-report >/dev/null
aws iam get-credential-report --output text --query Content \
  | base64 -d | cut -d, -f1,4,5,9,11,14

# ── GCP ──
gcloud projects get-iam-policy "$PROJECT_ID" \
  --flatten="bindings[].members" \
  --filter="bindings.members:user:" \
  --format="table(bindings.role, bindings.members)"
# user-managed service-account keys (inspect ages in the output)
listing=$(gcloud iam service-accounts list --format='value(email)')
for sa in $listing; do
  gcloud iam service-accounts keys list --iam-account="$sa" \
    --format="table(name.basename(), validAfterTime, keyType)" \
    --filter="keyType=USER_MANAGED"
done

# ── Azure ──
az ad user list --query "[].{upn:userPrincipalName, enabled:accountEnabled}" -o table
az ad sp list --all --query "[?passwordCredentials[0]!=null].{
  displayName:displayName,
  appId:appId,
  keyCount:length(passwordCredentials)
}" -o table

3. Secrets with no rotation date

# ── AWS Secrets Manager ──
aws secretsmanager list-secrets --query \
  "SecretList[?LastRotatedDate==null].[Name,LastChangedDate,LastAccessedDate]" \
  --output table
aws secretsmanager list-secrets --query \
  "SecretList[?LastRotatedDate!=null].[Name,LastRotatedDate]" \
  --output table

# ── GCP Secret Manager ──
gcloud secrets list --format="table(name, createTime, replication.automatic)"

# ── GitHub Actions org secrets (needs admin + gh) ──
gh api orgs/$ORG/actions/secrets --jq \
  '.secrets[] | [.name, .updated_at, .visibility] | @tsv'

# personal tokens still living in workflow files: search, then rotate
git grep -nE 'ghp_|gho_|github_pat_|AKIA[0-9A-Z]{16}' -- '*.yml' '*.yaml' || true

What you want is not a pretty report. It is three lists: services only one person touches, human identities with old keys, and secrets that have never been rotated. Those three lists are the order of week 1.

Where this breaks in practice

What remains when the notice period ends

Success for these thirty days is not a hired replacement or a new diagram. It is drier: two people can deploy, one critical key has been rotated with proof, four runbooks exist because they were executed, and the debt you did not touch has a name and an owner.

Hire afterwards. Or bring in backfill. But do not confuse the job post with the handover: one buys future time, the other buys the time you still have.


Send us the list of things only one person could do. We only rank three: whether somebody else can still deploy, whether a login or a 2FA phone leaves with them, and whether you can restore a backup without them. The rest: names, wikis, noisy alerts, waits. Within 24h you get those three back, and what the 30-day version of fixing them looks like.