atlas migrate drift now checks every target of an environment defined with for_each, such as a database or a schema per tenant, compares each one to the state of its own applied version, and reports it on its own.
atlas migrate drift now checks every target of an environment defined with for_each, such as a database or a schema per tenant. Each tenant is compared to the state of its own applied version and reported on its own, and a drifted tenant does not stop the run, so one command answers whether the whole fleet matches the migration directory.
The command is available to Atlas Pro users. Run atlas login to create an account or start a free trial. For the command itself, see the migrate drift entry.
Defining the Tenants
Define the tenants with for_each, exactly as for atlas migrate apply:
env "prod" {for_each = toset(["sqlite://tenants/t1.db", "sqlite://tenants/t2.db"])url = each.valuedev = "sqlite://file?mode=memory"migration {dir = "file://migrations"}}
One Report per Target
Every target is checked in turn. Here, a table was created out of band on the first tenant. The drift is reported for that tenant alone, the second tenant comes back clean, and the command exits with status 1.
$ atlas migrate drift --env prodDrift Status: DRIFTED-- Current Version: 1-- Expected State: file://migrations (local)-- Pending Files: 0-- Changes: 1 (1 extra)-- Objects: 1 table-- Fingerprint: 3062373192f2--- expected state (version 1)+++ actual state (sqlite://tenants/t1.db)@@ -0,0 +1,3 @@+CREATE TABLE `t10` (+ `c` int NULL+);The database diverged from the expected state as if the following were executed:-- extra table "t10":-> CREATE TABLE `t10` (`c` int NULL);Drift Status: OK-- Current Version: 1-- Expected State: file://migrations (local)-- Pending Files: 0
With --format, each tenant gets its own JSON report, so one run covers the whole group in an alerting or CI pipeline. See Multiple targets in the drift detection doc for the full behavior.