Skip to main content

SA Password & Rotation

The operator reads the SA password from the Secret named in spec.saPasswordSecret (key MSSQL_SA_PASSWORD). SQL Server itself only uses that value when it initializes an empty data volume; after first boot the password lives inside SQL Server. Since v0.1.11 the operator keeps the two in sync: changing the Secret rotates the password in SQL Server.

Rotating the SA password​

Update the Secret contents. Keep the same Secret name, because spec.saPasswordSecret is immutable:

kubectl create secret generic my-mssql-secret \
--from-literal=MSSQL_SA_PASSWORD='N3w-Str0ng!Password' \
--dry-run=client -o yaml | kubectl apply -f -

The operator rotates the password in two phases:

  1. Roll the pods. The pods restart one at a time onto a template that carries both the new password and the previous one (MSSQL_SA_PASSWORD_PREVIOUS). Availability Groups fail over gracefully through the preStop hook. Probes, the AG sidecar and the operator log in with whichever password SQL Server currently holds.
  2. Switch SQL Server. Once every pod runs the new template and is ready, the operator runs ALTER LOGIN [sa] WITH PASSWORD = ... on each replica (the SA login is per instance and is not replicated by the AG) and records the new password as applied.

The applied password is stored in the operator-owned Secret <name>-sa-applied. The resource stays Ready during the rotation. Clients must switch to the new password once the rotation completes; the sql-exporter sidecar cannot scrape until SQL Server is switched over.

  • The first rotation of a resource adds the previous-password plumbing to the pod template. Resources whose password was never rotated keep their template unchanged, so upgrading the operator does not restart them.
  • Editing the Secret again mid-rotation starts a new rotation towards the latest value. Reverting it to the applied password abandons the rotation.

Re-creating a resource over retained volumes​

PersistentVolumeClaims are kept when a resource is deleted, and so is <name>-sa-applied: it is owned by the resource and by its data PVCs, and is only garbage-collected once all of them are gone. If the resource is re-created with the same name while the PVCs still exist, the operator knows the password SQL Server holds and rotates it to whatever the Secret now contains, even if the Secret was regenerated in the meantime.

Password mismatch​

If SQL Server rejects every known password (the data volume was initialized with a password the operator no longer knows, for example because <name>-sa-applied was deleted or the PVCs came from elsewhere), the pods fail their probes and the resource reports the problem instead of crash-looping silently:

status:
state: Error
message: 'SQL Server on my-mssql-0 rejects the SA password in Secret "my-mssql-secret": the data volume was initialized with a different password'

Restore the original password into the Secret to recover. If it is lost, the only recovery today is to delete the resource and its PVCs (data loss), or to reset the password offline with mssql-conf set-sa-password against the data volume.