AWS: RDS / Aurora PostgreSQL with S3

RDS automated snapshots can't be downloaded as PostgreSQL backups (snapshot exports are Parquet), so keep a logical backup in S3 alongside them. That is also the copy an auditor means by "we can restore it anywhere".

1. Write dumps to S3

A scheduled ECS task, a small EC2 instance or a CI job runs:

pg_dump --format=custom --no-owner "$DATABASE_URL" \
  | aws s3 cp - "s3://acme-backups/orders/orders-$(date -u +%Y-%m-%dT%H-%M).dump"

2. Create a read-only IAM user (or role) for Verestore

Attach this policy. Replace the bucket name and prefix:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ListOnlyThePrefix",
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::acme-backups",
      "Condition": { "StringLike": { "s3:prefix": ["orders/*"] } }
    },
    {
      "Sid": "ReadOnlyThePrefix",
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::acme-backups/orders/*"
    }
  ]
}

If the bucket uses SSE-KMS, also allow decrypt through S3 only:

{
  "Sid": "DecryptViaS3Only",
  "Effect": "Allow",
  "Action": "kms:Decrypt",
  "Resource": "arn:aws:kms:eu-west-3:123456789012:key/KEY-ID",
  "Condition": { "StringEquals": { "kms:ViaService": "s3.eu-west-3.amazonaws.com" } }
}

Create an access key for the user and add the target in Verestore with endpoint https://s3.<region>.amazonaws.com, your region, bucket acme-backups and prefix orders/.