Skip to content

feat: active-active HA mode using Redis lease - #6750

Open
sakkiii wants to merge 14 commits into
runatlantis:mainfrom
sakkiii:ha-mode-with-redis
Open

feat: active-active HA mode using Redis lease#6750
sakkiii wants to merge 14 commits into
runatlantis:mainfrom
sakkiii:ha-mode-with-redis

Conversation

@sakkiii

@sakkiii sakkiii commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

what

Implements multi-replica active-active HA for Atlantis. Each PR is "owned" by one replica via a Redis lease. Webhooks arriving at a non-owning replica are forwarded over HTTP to the owner. Ownership renews every TTL/3 seconds. When a lease expires, another replica takes over.

Plan Storage Modes

Local Plans

Configuration:

--locking-db-type=redis
--replica-advertise-url=http://atlantis-0.atlantis-headless:4141
ATLANTIS_INTERNAL_COMMAND_TOKEN=<shared-secret>
--enable-external-stores=false
  • Planning writes .tfplan files only beneath the owner's data directory.
  • Commands continue to use owner-local plans while the ownership claim remains live.
  • After takeover, the new owner starts with an empty local pull directory.
  • Apply reports the normal missing working directory or missing plan error.
  • The user must run plan again before apply.

External Plans

Configuration:

--locking-db-type=redis
--replica-advertise-url=http://atlantis-0.atlantis-headless:4141
ATLANTIS_INTERNAL_COMMAND_TOKEN=<shared-secret>
--enable-external-stores=true
  • Planning writes locally and saves the plan through the existing external PlanStore.
  • Owner takeover clears only local state; remote plans remain available.
  • A targeted apply reclones the required workspace and loads its plan through the PlanStore.
  • Apply-all lists stored workspaces, clones them before restoration, and restores their plans for discovery.
  • The apply runner loads each plan and validates its stored head commit before Terraform executes.
  • A missing plan, absent commit metadata, or commit mismatch fails the command and requires re-plan.
  • External-store unavailability fails the command; Atlantis does not apply an unvalidated local fallback.
  • Successful apply and pull-close cleanup retain the existing best-effort removal behavior for external objects.

External storage does not remove the need for ownership. Ownership still provides pull request command ordering, stable local runtime state, forwarding, log locality, and cancellation affinity.

why

Implements multi-replica active-active HA for Atlantis. Each PR is "owned" by one replica via a Redis lease. Webhooks arriving at a non-owning replica are forwarded over HTTP to the owner. Ownership renews every TTL/3 seconds. When a lease expires, another replica takes over.

tests

  1. Redis configuration alone does not activate replica routing.
  2. Complete routing settings activate routing without an enable flag.
  3. Partial routing settings fail startup with a precise validation error.
  4. Replica ID defaults to the process hostname and supports an explicit override.
  5. Startup accepts replica routing with external storage configured.
  6. Scale-up leaves an existing pull request with its current owner.
  7. Graceful release permits lazy takeover by another replica.
  8. Lease expiry permits lazy takeover after owner failure.
  9. Local-plan takeover deletes stale local state and requires re-plan.
  10. External-plan takeover deletes stale local state, restores a matching plan, and permits apply.
  11. External-plan takeover rejects a plan from a different head commit.
  12. Missing or unavailable external plans fail without executing Terraform.
  13. Pull-close cleanup attempts external plan deletion before releasing ownership.
  14. Existing single-replica, Redis-only, and external-store-only modes remain unchanged.

references

closes #6751
closes #1571

Assisted-by: Claude

sakkiii added 5 commits August 8, 2026 14:49
Signed-off-by: Saket Mittal <s@sakkiii.in>
Signed-off-by: Saket Mittal <s@sakkiii.in>
Signed-off-by: Saket Mittal <s@sakkiii.in>
Signed-off-by: Saket Mittal <s@sakkiii.in>
Signed-off-by: Saket Mittal <s@sakkiii.in>
@dosubot dosubot Bot added feature New functionality/enhancement go Pull requests that update Go code labels Aug 9, 2026
@github-actions github-actions Bot added docs Documentation website labels Aug 9, 2026
@sakkiii sakkiii changed the title HA mode with Redis feat: HA mode with Redis Aug 9, 2026
Signed-off-by: Saket Mittal <s@sakkiii.in>
Signed-off-by: Saket Mittal <s@sakkiii.in>
Signed-off-by: Saket Mittal <s@sakkiii.in>
Signed-off-by: Saket Mittal <s@sakkiii.in>
- Updated the project command runner to re-check ownership before cloning or merging the working directory, ensuring that a replica that lost its lease does not mutate the working directory.
- Improved error handling during server shutdown to ensure all in-progress operations are drained properly, even if a shutdown error occurs.
- Adjusted tests to reflect changes in ownership verification logic, ensuring that ownership loss is handled correctly before executing commands.

Signed-off-by: Saket Mittal <s@sakkiii.in>
Updated the test for server shutdown behavior after HTTP timeout to ensure it completes all cleanup actions. The test now verifies that ownership release and database closure occur even when the HTTP shutdown deadline is missed, aligning with previous unconditional cleanup behavior.

Signed-off-by: Saket Mittal <s@sakkiii.in>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation feature New functionality/enhancement go Pull requests that update Go code website

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Atlantis HA mode using Redis Replica Routing Highly available cluster with multiple nodes

1 participant