--- created: 2026-08-28 modified: 2026-08-28 type: plan client: sam project: web-host-migration status: in_progress priority: 1 tags: - migration - aws - s3 - glacier - backup - iam aliases: - phase-1-aws-offsite id: 1848129019-P1 --- # Phase 1 — AWS Offsite Backup (initiate ASAP) > Part of [[Migration Plan — InMotion to Local + AWS Offsite]]. > **This is the current active phase.** Upstream: [[Phase 0 — Pre-flight]]. ## Goal Stand up an **AWS-only offsite backup** for `.13` (and photo archive) using the existing Borg pipeline, with **S3 → Glacier Deep Archive** lifecycle. Protect against burn-down / single-drive loss. ## Current verified state - `.13`: **no AWS CLI, no rclone, no credentials** — clean slate. - Borg managed by NixOS `backup.nix` (`services.borgbackup.jobs.*`, systemd timers, BORG_RSH wrapper). We extend this pattern. - Region: `ap-southeast-2` (Sydney). ## Sub-steps ### 1.1 AWS account + IAM (user does) - [x] Sign up at https://aws.amazon.com (root MFA, billing, phone) - [x] Set region to `ap-southeast-2` (Sydney) - [ ] **(built here)** Create least-privilege **IAM user** `backup-offsite` (programmatic): policy only `s3:PutObject/GetObject/ListBucket` on the backup bucket. NO console, NO Admin. - [ ] Create access key for that user (store in password manager; not in plaintext on disk). ### 1.2 Bucket + lifecycle (built here) - [ ] Create bucket `sam-offsite-backup` (region ap-southeast-2), **block public access**, **enable versioning**, **enable bucket key / server-side encryption (SSE-S3 or KMS)**. - [ ] **Lifecycle rule:** transition to **Glacier Flexible** after 30 days → **Glacier Deep Archive** after 90 days. (Optional: expire noncurrent versions to cap cost.) - [ ] Logging/object-lock: consider S3 Object Lock (compliance) as optional hardening — decide later. ### 1.3 Local tooling on `.13` (built here) - [ ] Install `rclone` (or `awscli`) via NixOS (add to `backup.nix` `packages` or environment.systemPackages). - [ ] Configure `rclone remote` (S3 API, access-key, region `ap-southeast-2`). Keep credentials in a root-owned file with 600 perms, referenced via NixOS secret pattern (mirror `.borg-passphrase` approach). ### 1.4 Offsite pipeline (built here) Choose approach (prefer **Borg → rclone → S3**, keeps existing repo + dedup): - [ ] **Borg to rclone remote** — add a new `services.borgbackup.jobs."offsite-to-aws"` repo `rclone:sambucket:borg/` via BORG_REPO / rclone backend. Schedule e.g. daily 07:00 (after local 04:00). - *Alternatively:* keep local-only Borg, then **rclone copy** the local repo tarball/repo → S3. Simpler, but double-stores dedup loses their value — prefer direct Borg-to-rclone if Borg-backend `rclone` works on 1.4.3. - [ ] **Seed first full backup** (photos + site data) to Glacier DA path. - [ ] **Test restore** of one archive from S3 → verify read path works (critical; document). ### 1.5 Monitoring & log - [ ] systemd timer health check; add an alert (ntfy/apprise) on failure (mirror existing pattern). - [ ] Record everything in [[Migration Work Log]]. ## Acceptance criteria - `rclone lsd sam-offsite-backup:` shows intended tree. - At least one acceptable test restore completed. - Cost projected < ~5 AUD/mo (photos in Glacier DA ~0.75–1.2/mo). ## Rollback / safety - Offsite is additive — local Borg + rsync + archive repos remain untouched. Turning off the new job restores prior state. --- *See [[Migration Plan — InMotion to Local + AWS Offsite]] §9 for cost model.*