Skip to content

Remediation

s.a.u never executes a destructive cloud operation without a compensation handler. Here is the full lifecycle.

Architecture Overview

sequenceDiagram
    participant User
    participant DEVI
    participant s.a.u
    participant Plugin

    User->>DEVI: "Quarantine this idle instance"
    DEVI->>SAU: request_quarantine(crn, justification)
    SAU->>User: HUMAN-IN-THE-LOOP: Approve?
    User->>SAU: Approved
    SAU->>Plugin: CheckReversibility(crn)
    Plugin-->>SAU: Safe=true (no termination protection)
    SAU->>Plugin: Remediate(crn, "stop", dry_run=true)
    Plugin-->>SAU: dry_run OK
    SAU->>Plugin: Remediate(crn, "stop", dry_run=false)
    Plugin-->>SAU: Success, snapshot={ami_id: "ami-xyz"}
    SAU->>SAU: Record CRDT DeltaState for rollback

Key principle: The engine never makes cloud API calls. Plugins do. The engine only knows about CRNs, actions, and snapshots.

The Remediation Lifecycle

Quarantine Request

DEVI or Human

# Via CLI
cloudslash quarantine crn:devi:aws:us-east-1:123:ec2:instance:i-0abc: action stop

Via the DEVI chat in the Web Dashboard or TUI:

"Stop the idle t2.micro in us-east-1"

DEVI calls the request_quarantine MCP tool. s.a.u intercepts and holds for human approval.

Human Approval

The TUI, Web UI, or Slack integration presents the quarantine request with:

  • The resource CRN
  • DEVI's justification
  • Estimated monthly savings
  • CheckReversibility result (are protection flags set?)

Pre-Flight Validation

// The engine calls the plugin's Remediate with dry_run=true
resp, err := plugin.Remediate(ctx, &RemediateRequest{
    Crn:    "crn:devi:aws:us-east-1:123:ec2:instance:i-0abc",
    Action: "stop",
    DryRun: true,
    Properties: map[string]string{
        "region": "us-east-1",
    },
})

Saga Execution

s.a.u wraps the remediation in a Saga with automatic rollback:

saga := &crdt.Saga{
    Steps: []crdt.Step{
        {
            Execute: func(ctx context.Context) error {
                // Record pre-remediation state snapshot
                return remediator.RecordState(ctx, node)
            },
            Compensate: func(ctx context.Context) error {
                // Restore from CRDT DeltaState
                return remediator.Restore(ctx, node)
            },
        },
        {
            Execute: func(ctx context.Context) error {
                // Call plugin.Remediate over gRPC
                return remediator.Purge(ctx, node)
            },
            Compensate: func(ctx context.Context) error {
                // Plugin-specific rollback using snapshot
                return remediator.Rollback(ctx, node, snapshot)
            },
        },
    },
}

Snapshot Recording

Every plugin returns a Snapshot map in the RemediateResponse:

Cloud Action Snapshot Contains
AWS EC2 stop ami_id (pre-stop AMI)
AWS EBS delete snapshot_id (EBS snapshot)
AWS RDS delete final_snapshot_id (DB snapshot)
GCP GCE stop operation (GCE operation name)
GCP Disk delete snapshot_name (GCE disk snapshot)
Azure VM stop resource_group, vm_name
Linode stop linode_id

Reversibility

Automatic Rollback

If any Saga step fails, s.a.u executes compensating operations in reverse order:

func (m *SAUEngine) rollback(ctx context.Context, s *Saga, failedIndex int) {
    // Detach from parent cancellation to guarantee rollback time
    unwindCtx, cancel := context.WithTimeout(
        context.WithoutCancel(ctx), 5*time.Minute,
    )
    defer cancel()

    for i := failedIndex - 1; i >= 0; i-- {
        _ = s.Steps[i].Compensate(unwindCtx)
    }
}

Manual Rollback

cloudslash undo crn:devi:aws:us-east-1:123:ec2:instance:i-0abc

s.a.u retrieves the CRDT DeltaState payload and re-creates the resource from the snapshot.

Plugin Remediation Actions

AWS Plugin

cloudslash-plugin-aws

Resource Action What Happens
EC2 Instance stop CreateImage (AMI) → StopInstances
EC2 Instance terminate TerminateInstances
EBS Volume delete CreateSnapshot → DeleteVolume
RDS Instance stop StopDBInstance
RDS Instance delete CreateFinalSnapshot → DeleteDBInstance
Lambda Function throttle PutFunctionConcurrency(0)

GCP Plugin

cloudslash-plugin-gcp

Resource Action What Happens
GCE Instance stop instances.Stop()
GCE Instance delete instances.Delete()
Persistent Disk delete CreateSnapshot → disks.Delete()
Cloud SQL stop Patch ActivationPolicy=NEVER
Cloud SQL delete instances.Delete()

Azure Plugin

cloudslash-plugin-azure

Resource Action What Happens
Virtual Machine stop BeginDeallocate()
Virtual Machine delete BeginDelete()
Managed Disk delete BeginDelete()
SQL Database stop BeginPause()
SQL Database delete BeginDelete()

Linode Plugin

cloudslash-plugin-linode

Resource Action What Happens
Linode Instance stop ShutdownInstance()
Linode Instance delete DeleteInstance()
Volume detach DetachVolume()
Volume delete DeleteVolume()
NodeBalancer delete DeleteNodeBalancer()

CheckReversibility

Before any remediation, the engine calls CheckReversibility to detect protection flags:

Cloud What It Checks
AWS EC2 termination protection (DisableApiTermination)
GCP GCE deletion protection (deletionProtection)
Azure do-not-delete tag, env=production tag
Linode production tag

If a protection flag is detected, the remediation is blocked and you are notified.