Skip to content
prod 352bb92
Browse

9 · Atlas Cloud

Objective — make one explicit end-of-phase Atlas Cloud adoption decision. If the project has an active Atlas Cloud license and adopts it now, register the selected non-production schema for versioned, team-visible migration tracking: open the SSH tunnel, build a baseline migration, push it to Atlas Cloud, apply the baseline, and wire up GitHub CI. If not, record N/A — no Atlas Cloud license/adoption and keep the page-5 schema dump + diff as the free baseline.

Steps at a glance:

  1. Open the SSH tunnel — Tunnel the selected non-production MySQL port to localhost so Atlas can reach it.
  2. Create the schema baseline — Export the live selected target schema and generate a baseline migration from it.
  3. Push to Atlas Cloud — Publish the baseline migration directory to Atlas Cloud.
  4. Apply the baseline to the selected target — Register the selected target against the pushed baseline and confirm it’s synced.
  5. Wire up GitHub CI — Gate future schema changes through CI by registering a cloud token and the cloud environments.

Atlas Cloud is a paid/hosted layer. Default to skip unless the project already has an active license and intentionally adopts it for this app.

Whether to do this page at all:

flowchart LR
Tunnel[SSH tunnel to non-production DB] --> Baseline[Register baseline migration]
Baseline --> Atlas[Atlas Cloud ERD]
Change[Future schema change] --> CI[CI migration gate]
CI --> Atlas

Tunnel the selected non-production MySQL port to localhost so Atlas can reach it. Use the environment row from Zaj-PROJECT.md (staging-primary, qa, uat, client-demo, etc.); staging is only the common example.

  1. Open the tunnel and confirm the non-production URL is set.

    Terminal window
    NON_PROD_SSH_ALIAS="<alias-from-Zaj-PROJECT.md>"
    ssh -L 3307:127.0.0.1:3306 "$NON_PROD_SSH_ALIAS" -N &
    ps aux | grep "ssh -L"
    echo "Non-production URL: $ATLAS_NON_PROD_URL" # if empty, run `direnv allow` in the project root
    # Expected: the tunnel process is running; $ATLAS_NON_PROD_URL is non-empty
    • ✅ The tunnel is up and $ATLAS_NON_PROD_URL resolves.

Export the live selected non-production schema and generate a baseline migration from it.

  1. Inspect, diff, and mark the baseline applied locally.

    Terminal window
    # Backup existing migrations before rebuild (never blind rm)
    ATLAS_MIG_DIR=packages/ZajModules/Database/Atlas/migrations
    if [ -d "$ATLAS_MIG_DIR" ] && [ "$(ls -A "$ATLAS_MIG_DIR" 2>/dev/null)" ]; then
    mv "$ATLAS_MIG_DIR" "${ATLAS_MIG_DIR}.bak.$(date +%Y%m%d-%H%M%S)"
    fi
    mkdir -p "$ATLAS_MIG_DIR"
    # Export the live selected target schema
    atlas schema inspect -u "$ATLAS_NON_PROD_URL" --format '{{ sql . }}' \
    > packages/ZajModules/Database/Atlas/schema/current.sql
    grep -c "CREATE TABLE" packages/ZajModules/Database/Atlas/schema/current.sql # sanity-check table count
    # Generate the baseline migration
    atlas migrate diff baseline \
    --dir "file://packages/ZajModules/Database/Atlas/migrations" \
    --to "file://packages/ZajModules/Database/Atlas/schema/current.sql" \
    --dev-url "docker://mysql/8/dev"
    # Mark it applied locally (substitute the generated timestamp)
    atlas migrate apply \
    --dir "file://packages/ZajModules/Database/Atlas/migrations" \
    --url "$ATLAS_LOCAL_URL" \
    --baseline "YOUR_TIMESTAMP"
    # Expected: a baseline migration generated and marked applied against the local URL
    • ✅ A baseline migration is generated from the selected target schema and marked applied locally.

Publish the baseline migration directory to Atlas Cloud.

  1. Push the migrations directory.

    Terminal window
    atlas migrate push YOUR_PROJECT_NAME \
    --dir "file://packages/ZajModules/Database/Atlas/migrations" \
    --dev-url "docker://mysql/8/dev"
    # Expected: a project URL is returned; the ERD tab shows your tables
    • ✅ The push returns a URL and the ERD tab shows your tables.

Open the returned URL — the ERD tab should show your tables.

4. Apply the baseline to the selected target

Section titled “4. Apply the baseline to the selected target”

Register the selected target against the pushed baseline and confirm it’s synced.

  1. Apply the baseline and check status.

    Terminal window
    atlas migrate apply \
    --dir "file://packages/ZajModules/Database/Atlas/migrations" \
    --url "$ATLAS_NON_PROD_URL" \
    --baseline "YOUR_TIMESTAMP"
    atlas migrate status \
    --dir "file://packages/ZajModules/Database/Atlas/migrations" \
    --url "$ATLAS_NON_PROD_URL"
    # expect: Migration Status: OK
    • Migration Status: OK — the selected target is registered and synced.

Gate future schema changes through CI by registering a cloud token and the cloud environments.

  1. Copy the token, set the secret, and register the databases.

    1. Atlas Cloud → Set Up CI → GitHub → CLI → copy the token (aci_…).

    2. Store the secret without putting the token in shell history:

      Terminal window
      printf '%s' 'aci_…' | gh secret set ATLAS_CLOUD_TOKEN --repo OWNER/REPO
      # Or: gh secret set ATLAS_CLOUD_TOKEN < /path/to/token-file
    3. Add the cloud environments to atlas.hcl.

    4. Register databases: atlas migrate apply --env cloud-staging --baseline "YOUR_TIMESTAMP" (example environment name; use the Atlas env name mapped to ENV_KEY).

    • ✅ The CI token is stored as ATLAS_CLOUD_TOKEN, cloud envs are in atlas.hcl, and databases are registered.

Do not mark this step done until every box below is checked.

  • 🤖 Baseline created — baseline migration created from the selected target schema.
  • 🤖 Pushed to Atlas Cloud — ERD renders correctly.
  • 🤖 Target synced — selected target registered and showing “Synced” (migrate status: OK).
  • 🔀 CI configured — GitHub CI token configured (ATLAS_CLOUD_TOKEN) (👤 copy token from Atlas Cloud).
  • 🔵 Or N/A recorded — if Atlas Cloud is not adopted, the run records N/A with the license/adoption reason and relies on the page-5 schema dump + diff baseline.

That closes the optional non-production tracks. Continue to Phase 6 · SuperAdmin setup — brand and configure the app on the selected non-production target.