Skip to content

Add postgres_snapshot_schedules bundle resource - #6449

Draft
janniklasrose wants to merge 5 commits into
bump-sdk-v0.177.0from
janniklasrose/postgres-snapshot-schedules
Draft

Add postgres_snapshot_schedules bundle resource#6449
janniklasrose wants to merge 5 commits into
bump-sdk-v0.177.0from
janniklasrose/postgres-snapshot-schedules

Conversation

@janniklasrose

@janniklasrose janniklasrose commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Caution

Stacked on #6448 but still missing the TF bump

Changes

Add the postgres_snapshot_schedules bundle resource, which manages the automatic-snapshot schedule of a Lakebase Postgres branch.

The snapshot schedule is a per-branch singleton with no create or delete API — only GetSnapshotSchedule and UpdateSnapshotSchedule. The resource maps the lifecycle onto that single write call:

  • create/update set the branch's schedule via UpdateSnapshotSchedule (update_mask schedule, awaiting the long-running operation);
  • delete disables automatic snapshots by setting an empty cadence set, since DoDelete also fires when the resource is removed from config, not only on bundle destroy;
  • branch composes the schedule's hierarchical name and is a provided id field (a change recreates).

Modeled on the existing postgres_* resources. Direct engine only: the schedule was added in databricks-sdk-go v0.177.0 and the pinned Terraform provider has no equivalent resource yet, so the acceptance and bind tests are pinned to the direct engine.

Tests

  • direct-engine unit CRUD (bundle/direct/dresources);
  • acceptance: basic deploy/read/destroy and an update (in-place cadence change), plus the invariant and bind/unbind suites;
  • resource-enumeration unit tests (bind support, run_as, permissions, target-mode) extended for the new type.

Acceptance goldens regenerated via -update; the verify pass is green apart from pre-existing load-induced terraform-engine timeout flakes, each confirmed passing in isolation.

@janniklasrose
janniklasrose force-pushed the janniklasrose/postgres-snapshot-schedules branch from a34c52d to f1196c2 Compare August 31, 2026 20:29
## Changes

Add the `postgres_snapshot_schedules` bundle resource, which manages the
automatic-snapshot schedule of a Lakebase Postgres branch.

The snapshot schedule is a per-branch singleton with no create or delete API —
only `GetSnapshotSchedule` and `UpdateSnapshotSchedule`. The resource maps the
lifecycle onto that single write call:

- create/update set the branch's schedule via `UpdateSnapshotSchedule`
  (update_mask `schedule`, awaiting the long-running operation);
- delete disables automatic snapshots by setting an empty cadence set, since
  DoDelete also fires when the resource is removed from config, not only on
  `bundle destroy`;
- `branch` composes the schedule's hierarchical name and is a provided id field
  (a change recreates).

Modeled on the existing `postgres_*` resources. Direct engine only: the schedule
was added in databricks-sdk-go v0.177.0 and the pinned Terraform provider has no
equivalent resource yet, so the acceptance and bind tests are pinned to the
direct engine.

## Tests

- direct-engine unit CRUD (`bundle/direct/dresources`);
- acceptance (direct engine), four end-to-end scenarios, each reading the
  schedule back with `postgres get-snapshot-schedule`:
  - `basic`: create with a cadence, in-place cadence update, then remove the
    resource from config, which disables the schedule (reads back
    `schedule: null`);
  - `update`: add the schedule to an already-deployed branch, then remove it;
  - `out-of-band`: an out-of-band `update-snapshot-schedule` is detected as
    drift by `bundle plan` (`update postgres_snapshot_schedules.main_schedule`)
    and reconciled back by deploy;
  - `orphaned`: removing the branch from config while keeping the schedule that
    references it — the reference still resolves from the deployed state, so
    validate passes and plan sequences a branch delete alongside a schedule
    recreate (documented, not a validation error);
- the invariant and bind/unbind suites;
- resource-enumeration unit tests (bind support, run_as, permissions,
  target-mode) extended for the new type.

Acceptance goldens regenerated via `-update`; the verify pass is green apart
from pre-existing load-induced terraform-engine timeout flakes, each confirmed
passing in isolation.

Co-authored-by: Isaac <no-reply@databricks.com>
@janniklasrose
janniklasrose force-pushed the janniklasrose/postgres-snapshot-schedules branch from 4c0b285 to 686d31b Compare September 1, 2026 08:08
janniklasrose and others added 3 commits September 1, 2026 08:34
Drop the `update` subtest (create/update/remove is already covered by
`basic`) and the `orphaned` subtest (deleting a branch while keeping a
schedule that references it is user error — it plans but fails at apply,
which we don't need to pin in a golden).

Co-authored-by: Isaac <no-reply@databricks.com>
DoCreate built the schedule resource name as `config.Branch + "/snapshot-schedule"`,
which doubles the separator if a user writes `branch:` with a trailing slash.
Route it through snapshotScheduleName, which trims trailing slashes first, and
cover it with a unit test.

Co-authored-by: Isaac <no-reply@databricks.com>
Add a `bundle plan` after the removal step in the basic acceptance test; it
reports "0 to add, 0 to change, 0 to delete" (project and branch unchanged),
confirming the disable settled cleanly and leaves no lingering drift.

Co-authored-by: Isaac <no-reply@databricks.com>
Comment on lines -1132 to +1167
deleteIsNoop := strings.HasSuffix(group, "permissions") || strings.HasSuffix(group, "grants")
// postgres_snapshot_schedules has no delete endpoint: DoDelete disables the
// schedule by setting an empty cadence set, and the schedule remains readable
// (it is intrinsic to the branch), so DoRead still succeeds afterwards.
deleteIsNoop := strings.HasSuffix(group, "permissions") || strings.HasSuffix(group, "grants") || group == "postgres_snapshot_schedules"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can rename deleteIsNoop? It implies that DoDelete does nothing, but it does (at least to the best of its abilities, updating it to the default empty object)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant