Skip to main content

Restic Backup: SFTP backend

Deploy a restic backup repository backed by SFTP. See Restic backup for the backend-agnostic overview, shared variables, and installation.

Ansible hosts group: restic​

Variables: shared​

Shared variables are documented on the Restic backup page.

Variables​

OptionTypeDescriptionDefault
cs_restic_sftp_repos_rootstringPath to SFTP repositories root/app/{{ cs_restic_cluster_name }}-restic
cs_restic_sftp_repos_group_namestringGroup name for SFTP reposrestic

Server-side setup (tasks/restic_setup_repositories/sftp-main.yml, tasks/restic_setup_repositories/sftp-repo.yml)​

For each repository defined in cs_restic_repos, the following steps are performed on the restic host:

  • A group (cs_restic_sftp_repos_group_name) is created.
  • A dedicated user restic-<repo_name> is created in that group with the /bin/bash shell, an unlocked password state, and a home directory at /home/restic-<repo_name>.
  • An ed25519 SSH key pair is generated in the user's home directory and read back, and both key files are then deleted. The private key (PEM) is written to Vault; the public key is added as an authorized key for the user.
  • The repository root directory (cs_restic_sftp_repos_root) is created if absent (mode 0755).
  • If <cs_restic_sftp_repos_root>/<repo_name>/config does not exist, the repository is initialized using restic init --verbose with a random 64-character password and RESTIC_REPOSITORY=<repos_root>/<repo_name> (a local path on the restic host). On failure, the partially created repository directory is removed.
  • After a successful init, the repository password is written to Vault. An existing repository keeps the password already in Vault.
  • Ownership of <cs_restic_sftp_repos_root>/<repo_name> is set recursively to user restic-<repo_name> and group cs_restic_sftp_repos_group_name.
  • The repository is validated: the repository password is read back from Vault and restic snapshots --verbose is run against the repository.

Backup and restore (restic_backup_restore_sftp)​

Module for performing a backup or restore operation against an SFTP-backed restic repository. The caller is responsible for reading SSH credentials and the repository password from Vault (see Vault keys below) and passing them to the module; the module writes the private key to a temporary file, runs the appropriate restic command, then runs restic snapshots and restic check to validate the repository once that command succeeds, and removes the temporary key file regardless of outcome.

Behavior​

  • Backup: runs restic backup --verbose -o sftp.args="-o IdentityFile=<key_file> -o StrictHostKeyChecking=no" --host <restic_host> <local_dir>.
  • Restore: runs restic restore latest --verbose --target <local_dir> -o sftp.args="-o IdentityFile=<key_file> -o StrictHostKeyChecking=no" --host <restic_host>.
  • RESTIC_REPOSITORY is constructed as sftp:<ssh_user>@<ssh_host>:<repo_path>.
  • The private key is written to a temp file (mode 0600) and deleted after the operation regardless of outcome.
  • restic snapshots --verbose and restic check --verbose run after every successful backup or restore; their output is returned in snapshots_stdout_lines / check_stdout_lines.

Example​

- name: App | Restic Backup | Backup
restic_backup_restore_sftp:
ops: backup
local_dir: /var/lib/my-app
restic_host: '{{ inventory_hostname }}'
ssh_user: '{{ restic_repo_access.user }}'
ssh_host: '{{ restic_repo_access.host }}'
repo_path: '{{ restic_repo_access.path }}'
private_key: '{{ restic_repo_access.private_key }}'
repo_password: '{{ restic_repo_password.repository_password }}'
vars:
restic_repo_access: "{{ lookup('vault_kv_get',
cs_project_code + '/application-deployer/clusters/' + cs_restic_cluster_name + '/hosts/' + inventory_hostname
+ '/apps/restic/generated/sftp-repository-access-my-repo') }}"
restic_repo_password: "{{ lookup('vault_kv_get',
cs_project_code + '/application-deployer/clusters/' + cs_restic_cluster_name + '/hosts/' + inventory_hostname
+ '/apps/restic/generated/sftp-repository-password-my-repo') }}"

Vault keys​

SFTP access credentials​

Key: {{ cs_project_code }}/application-deployer/clusters/{{ cs_restic_cluster_name }}/hosts/{{ inventory_hostname }}/apps/restic/generated/sftp-repository-access-{{ repo_name }}

{
"private_key": "Ed25519 private key (PEM) used for SFTP authentication.",
"user": "restic-<repo_name>",
"host": "ansible_host value of the restic server.",
"hostname": "ansible_hostname value of the restic server.",
"fqdn": "ansible_fqdn value of the restic server.",
"path": "<cs_restic_sftp_repos_root>/<repo_name>"
}

Repository password​

Key: {{ cs_project_code }}/application-deployer/clusters/{{ cs_restic_cluster_name }}/hosts/{{ inventory_hostname }}/apps/restic/generated/sftp-repository-password-{{ repo_name }}

{
"repository_password": "Restic repository encryption password."
}