A new AtlasDriftCheck resource checks an AtlasMigration database for drift on a schedule and reports the results through its status and Kubernetes events.
The Atlas Kubernetes Operator now includes an AtlasDriftCheck resource for checking an AtlasMigration database for drift on a schedule. It runs atlas migrate drift against the database and reports the result through the resource status, conditions, and Kubernetes events. It never modifies the database.
The pre-apply drift check configured with policy.drift can block a deployment when the database has drifted, but it only checks when a deployment runs. AtlasDriftCheck runs independently on a schedule, so it can detect manual changes made between deployments.
apiVersion: db.atlasgo.io/v1alpha1kind: AtlasDriftCheckmetadata:name: myapp-driftspec:targetRef:name: myapp # an AtlasMigration in the same namespaceinterval: 5monDrift: Report # Report (default) or Failexclude:- "public.audit_*"- "*[type=extension]"
The check requires an Atlas Pro token. It authenticates using the target's cloud.tokenFrom, which references a bot token.
Options
| Field | Default | Notes |
|---|---|---|
| targetRef.name | - | Required. The name of an AtlasMigration in the same namespace. |
| interval | 5m | Time between checks. The minimum is 1m. A random delay of up to 10% is added to spread checks over time. |
| timeout | 5m | Maximum time allowed for a single check. |
| suspend | false | Pauses scheduled checks while preserving the last result. |
| onDrift | Report | Report sets Drifted=True while keeping Ready=True. Fail also sets Ready=False and Stalled=True. |
| exclude | - | Glob patterns for objects to ignore. By default, the check uses the target's policy.drift.exclude. If specified here, this list replaces the target's list rather than merging with it. |
Expected State
Unlike policy.drift, AtlasDriftCheck supports both registry and local migration directories. The source used to determine the expected state is recorded in status.mode:
- registry: When the target uses dir.remote, Atlas reads the state of the applied version from the Atlas Registry. Only an untagged atlas migrate push uploads this state. A push with a tag uploads only the migration files.
- local: When the target uses a local migration directory (dir.local or a ConfigMap), it must also define spec.devURL or spec.devURLFrom. Atlas determines the expected state by replaying the migration directory on that dev database. The operator does not create a dev database for the check.
If the registry does not contain state for the applied version and the target has a dev URL, Atlas falls back to replaying the migration directory. In this case, status.mode is local.
Status and Events
After each check, the resource status records the applied version, expected-state mode, a summary of drifted objects, and the time of the check. kubectl get atlasdriftchecks displays these values as columns.
The Drifted condition reports the current result:
Drifted=False NoDrift: no drift detected at version 20250901000000Drifted=True DriftDetected: 2 drifted objects (extra 1, modified 1) at version 20250901000000: table 2
Events are emitted only when the drift state changes, rather than after every check:
| Event | Type | When |
|---|---|---|
| DriftDetected | Warning | The database changes from clean to drifted. |
| DriftChanged | Warning | The database remains drifted, but the detected drift changes. |
| DriftResolved | Normal | The database changes from drifted to clean. |
| CheckFailed | Warning | A check cannot run. The same failure is not emitted repeatedly. |
The status does not include DDL statements. To inspect the statements associated with the drift, run atlas migrate drift from the CLI.
Behavior
- If the target is applying migrations or a deployment holds the database lock, the check preserves its last result and retries after about 30 seconds.
- If a check cannot run, Drifted becomes Unknown while the last result is preserved. Errors that require configuration changes, such as a missing target or a local migration directory without a dev database, also set Stalled=True. These errors are retried at the configured interval.
- The check does not watch the target for changes. Updates to the target, such as configuring a new dev URL, take effect on the next scheduled check.
- The target must be an AtlasMigration resource in the same namespace. Environments that use for_each are not supported.
See the drift detection documentation.