{
  "namespace": "observability",
  "region": "prod-aws-ap-southeast-1",
  "retentionWindow": {
    "end": "2026-08-13T00:00:00Z",
    "start": "2026-05-27T00:00:00Z"
  },
  "shardStepInterval": "6h",
  "sourceReplicaCount": 24,
  "steps": {
    "prepare": {
      "items": [
        {
          "name": "preflight",
          "desc": "Describe the VMCluster; manually confirm Ready status, frozen vmagent split rules, and target cluster readiness",
          "command": [
            "kubectl -n observability describe vmcluster vmcluster"
          ]
        },
        {
          "name": "generate-tenants",
          "desc": "Generate the tenant lists, flatten them with `vm-migration tenants merge`, then pass the flat list to `plan compile` via --tenants (example commands — adjust flags per environment)",
          "command": [
            "# Example commands — adjust flags per environment (see vm-migration tenants --help).",
            "vm-migration tenants dedicated k8s --output tenants-dedicated-k8s.json",
            "vm-migration tenants dedicated s3 --s3-bucket <bucket> --output tenants-dedicated-s3.json",
            "vm-migration tenants essential mgmt --addr <addr> --region <region> --provider <provider> --output essential-mgmt.json",
            "vm-migration tenants essential rds --clusters-in essential-mgmt.json --secret-file <secret-file> --db-host <db-host> --output essential-rds.json",
            "vm-migration tenants essential s3 --clusters-in essential-rds.json --s3-bucket <bucket> --output tenants-essential.json",
            "vm-migration tenants merge --input tenants-dedicated-k8s.json --input tenants-dedicated-s3.json --input tenants-essential.json --output tenants.json"
          ]
        },
        {
          "name": "enable-dedup",
          "desc": "Patch VMCluster vmselect.extraArgs dedup.minScrapeInterval=1ms; idempotent",
          "command": [
            "yq -i 'with(select(.kind == \"VMCluster\"); .spec.vmselect.extraArgs.\"dedup.minScrapeInterval\" = \"1ms\")' <repo-path>/deployments/dataplane/vmcluster/envs/<region>/vmcluster.yaml",
            "git -C <repo-path> diff -- deployments/dataplane/vmcluster/envs/prod-aws-ap-southeast-1/vmcluster.yaml",
            "# Review the diff above; commit and push when ready (not done by this tool). Wait for ArgoCD sync before proceeding to the next stage."
          ]
        },
        {
          "name": "drain-insert",
          "desc": "Patch maintenanceInsertNodeIDs=[6..23]; new writes hash only to vmstorage-0..5",
          "command": [
            "yq -i 'with(select(.kind == \"VMCluster\"); .spec.vmstorage.maintenanceInsertNodeIDs = [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23])' <repo-path>/deployments/dataplane/vmcluster/envs/<region>/vmcluster.yaml",
            "git -C <repo-path> diff -- deployments/dataplane/vmcluster/envs/prod-aws-ap-southeast-1/vmcluster.yaml",
            "# Review the diff above; commit and push when ready (not done by this tool). Wait for ArgoCD sync before proceeding to the next stage."
          ]
        },
        {
          "name": "deploy-vmselects",
          "desc": "Deploy both temporary vmselects via the serve API: vmselect-migration on 6..23 (vmctl export source) and vmselect-candidate on 0..5 (verification query path)",
          "command": [
            "# The migration must exist on serve first: curl -X POST <serve>/migrations/<name> --data-binary @<compiled-plan.json>",
            "curl -X POST <serve>/migrations/<name>/deploy",
            "curl -N <serve>/migrations/<name>/logs"
          ]
        }
      ]
    },
    "migration": {
      "items": [
        {
          "name": "run",
          "desc": "Dispatch the migrate-run job (the per-tenant loop sequence is fixed in the tool; see the runbook overview); re-POST resumes incomplete tenants",
          "command": [
            "# Runbook Phase 2 first: probe and estimate, tune only from probe evidence.",
            "curl -X POST <serve>/migrations/<name>/run",
            "curl -N <serve>/migrations/<name>/logs",
            "# Completion gate: poll until done == total and failed == 0.",
            "curl '<serve>/migrations/<name>/summary?format=text'"
          ]
        }
      ]
    },
    "decommission": {
      "items": [
        {
          "name": "drain-select",
          "desc": "Patch maintenanceSelectNodeIDs=[6..23]; production queries no longer touch vmstorage-6..23",
          "command": [
            "yq -i 'with(select(.kind == \"VMCluster\"); .spec.vmstorage.maintenanceSelectNodeIDs = [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23])' <repo-path>/deployments/dataplane/vmcluster/envs/<region>/vmcluster.yaml",
            "git -C <repo-path> diff -- deployments/dataplane/vmcluster/envs/prod-aws-ap-southeast-1/vmcluster.yaml",
            "# Review the diff above; commit and push when ready (not done by this tool). Wait for ArgoCD sync before proceeding to the next stage."
          ]
        },
        {
          "name": "scale-down",
          "desc": "Patch vmstorage.replicaCount=6; StatefulSet removes pods 6..23 in reverse order while PVCs are retained",
          "command": [
            "yq -i 'with(select(.kind == \"VMCluster\"); .spec.vmstorage.replicaCount = 6)' <repo-path>/deployments/dataplane/vmcluster/envs/<region>/vmcluster.yaml",
            "git -C <repo-path> diff -- deployments/dataplane/vmcluster/envs/prod-aws-ap-southeast-1/vmcluster.yaml",
            "# Review the diff above; commit and push when ready (not done by this tool). Wait for ArgoCD sync before proceeding to the next stage."
          ]
        },
        {
          "name": "cleanup",
          "desc": "Undeploy vmselect-migration and vmselect-candidate after the rollback window closes",
          "command": [
            "curl -X POST <serve>/migrations/<name>/undeploy",
            "curl -N <serve>/migrations/<name>/logs"
          ]
        }
      ]
    }
  },
  "targetReplicaCount": 6,
  "tenants": [
    "0:0",
    "10317:0",
    "10318:0",
    "11136:0",
    "11137:0",
    "11176:0",
    "112:168274",
    "112:172283",
    "112:176183",
    "112:176555",
    "112:182614",
    "112:184965",
    "112:185276",
    "112:186036",
    "112:186116",
    "112:189684",
    "112:195339",
    "112:197404",
    "112:199562",
    "112:206466",
    "112:206590",
    "112:206696",
    "112:206814",
    "112:207003",
    "112:207035",
    "112:207997",
    "112:208085",
    "112:209368",
    "112:212368",
    "112:213294",
    "112:213333",
    "112:227527",
    "112:227563",
    "112:227592",
    "112:229501",
    "112:230100",
    "112:230225",
    "112:231143",
    "112:231271",
    "112:231654",
    "112:235447",
    "112:235449",
    "112:235824",
    "112:235866",
    "112:236031",
    "112:236917",
    "112:237573",
    "112:237589",
    "112:238060",
    "112:238062",
    "112:238473",
    "112:240799",
    "11465:0",
    "11466:0",
    "11528:0",
    "11570:0",
    "11600:0",
    "11689:0",
    "11754:0",
    "12049:0",
    "12050:0",
    "12165:0",
    "12166:0",
    "12177:0",
    "12195:0",
    "12196:0",
    "12261:0",
    "12275:0",
    "12462:0",
    "12469:0",
    "12470:0",
    "12495:0",
    "12502:0",
    "12517:0",
    "12518:0",
    "12519:0",
    "12520:0",
    "12521:0",
    "12542:0",
    "12553:0",
    "12588:0",
    "12589:0",
    "12590:0",
    "12592:0",
    "12593:0",
    "12594:0",
    "12595:0",
    "12596:0",
    "12597:0",
    "12598:0",
    "12599:0",
    "12600:0",
    "12601:0",
    "12602:0",
    "12603:0",
    "12604:0",
    "12605:0",
    "12606:0",
    "12607:0",
    "12608:0",
    "12609:0",
    "12652:0",
    "12653:0",
    "12654:0",
    "12655:0",
    "12656:0",
    "12662:0",
    "12663:0",
    "12732:0",
    "12733:0",
    "12734:0",
    "12735:0",
    "12792:0",
    "12793:0",
    "12794:0",
    "12795:0",
    "12812:0",
    "12813:0",
    "12814:0",
    "12815:0",
    "12816:0",
    "12817:0",
    "12818:0",
    "12819:0",
    "249:0",
    "285:0",
    "2992:0",
    "3071:0",
    "3082:0",
    "3112:0",
    "3113:0",
    "3174:0",
    "3175:0",
    "3339:0",
    "33:0",
    "3446:0",
    "3447:0",
    "3466:0",
    "3494:0",
    "3498:0",
    "3499:0",
    "37:0",
    "42:0",
    "4572:0",
    "45:0",
    "47:0",
    "49:0",
    "6482:0",
    "6483:0"
  ],
  "vmcluster": {
    "name": "vmcluster",
    "vminsertName": "vminsert-vmcluster",
    "vminsertURLPattern": "http://vminsert-vmcluster.observability.svc.cluster.local:8480/insert/{tenant}/prometheus",
    "vmselectName": "vmselect-vmcluster",
    "vmselectURLPattern": "http://vmselect-vmcluster.observability.svc.cluster.local:8481/select/{tenant}/prometheus"
  },
  "vmctl": {
    "concurrency": 4,
    "rateLimitBytes": null,
    "stepInterval": "day"
  },
  "vmselects": {
    "image": "557537366020.dkr.ecr.us-west-2.amazonaws.com/victoriametrics/vmselect:v1.122.2-cluster",
    "migration": {
      "name": "vmselect-migration",
      "urlPattern": "http://vmselect-migration.observability.svc.cluster.local:8481/select/{tenant}/prometheus",
      "replicas": 2,
      "resources": {
        "limits": {
          "cpu": "1",
          "memory": "4Gi"
        },
        "requests": {
          "cpu": "0.5",
          "memory": "2Gi"
        }
      }
    },
    "candidate": {
      "name": "vmselect-candidate",
      "urlPattern": "http://vmselect-candidate.observability.svc.cluster.local:8481/select/{tenant}/prometheus",
      "replicas": 1,
      "resources": {
        "limits": {
          "cpu": "1",
          "memory": "4Gi"
        },
        "requests": {
          "cpu": "0.5",
          "memory": "2Gi"
        }
      }
    }
  }
}
