# backup-verify — weekly "a backup is not trusted until restored" (CONTRACT_004 # §4.6, T14 state-dependent half). Produces a fresh bundle and asserts it restores # from the OFFSITE copy into scratch resources (NON-DESTRUCTIVE — restore.sh never # touches the live platform). Runs on the foundation's own runner in foundation-ci. # # It reuses the operator scripts UNCHANGED (backup/backup.sh + restore.sh), which # read everything from `pulumi config get` (vm coords, vault root token, offsite + # age creds — all in the committed, passphrase-encrypted Pulumi.foundation.yaml) and # orchestrate the heavy lifting on the VM over SSH (ADR-007). Two CI-specific needs: # 1. the operator SSH key (SSH_PRIVATE_KEY secret → /tmp/op_key) to reach the VM; # 2. real Pulumi STATE imported into a file backend, because backup.sh embeds a # `pulumi stack export` (pulumi-state.json, CONTRACT_004 §4.2) in the bundle — # a bare `stack init` would ship an EMPTY deployment. State is pulled from the # object run.sh publishes (state-publish.sh), same as pulumi-preview. # # Schedule only (+ manual dispatch): never on push — it creates real backup bundles. name: backup-verify on: schedule: - cron: "17 3 * * 0" # weekly, Sunday 03:17 UTC workflow_dispatch: jobs: backup-verify: runs-on: docker container: image: foundation-ci:latest env: PULUMI_CONFIG_PASSPHRASE: ${{ secrets.PULUMI_CONFIG_PASSPHRASE }} SSH_PRIVATE_KEY_PATH: /tmp/op_key PULUMI_SKIP_UPDATE_CHECK: "true" steps: - uses: actions/checkout@v4 - name: Materialize operator SSH key (reaches the VM over SSH) env: SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} run: | install -m 600 /dev/null /tmp/op_key printf '%s' "$SSH_PRIVATE_KEY" > /tmp/op_key [ -z "$(tail -c1 /tmp/op_key)" ] || printf '\n' >> /tmp/op_key - name: Import Pulumi state (so the bundle's pulumi-state.json is real) env: RUSTFS_ACCESS_KEY: ${{ secrets.RUSTFS_ACCESS_KEY }} RUSTFS_SECRET_KEY: ${{ secrets.RUSTFS_SECRET_KEY }} working-directory: bootstrap run: | mc alias set rfs http://foundation-rustfs:9000 "$RUSTFS_ACCESS_KEY" "$RUSTFS_SECRET_KEY" >/dev/null mc cp rfs/foundation-ci-state/foundation-stack.json /tmp/foundation-stack.json mkdir -p state export PULUMI_BACKEND_URL="file://$(pwd)/state" pulumi stack select foundation 2>/dev/null || pulumi stack init foundation pulumi stack import --file /tmp/foundation-stack.json - name: Backup, then restore-verify from offsite (CONTRACT_004 §4.6) run: | TS=$(date -u +%Y%m%dT%H%M%SZ) echo "backup-verify: bundle timestamp $TS" ./backup/backup.sh "$TS" ./backup/restore.sh "$TS" off echo "backup-verify: OK ($TS restored from offsite)"