Skip to content

borgbase/ansible-role-rustic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ansible role for Rustic

This role will setup Rustic backups on a Linux machine using a systemd service and timer. It focuses on simplicity and avoids adding another layer of complexity by using rustic's built-in configuration file support.

Rustic is a fast, encrypted, deduplicated backup tool written in Rust. It's compatible with restic repositories but offers better performance.

Role Variables

Rustic installation

The role will download and install the rustic binary (version rustic_version) into rustic_path if the file does not exist.

  • rustic_version: Version of rustic to install (default: "latest")
  • rustic_path: Installation path for the binary (default: /usr/local/bin/rustic)

Rustic configuration

  • rustic_config_dir: Directory for rustic configuration (default: /etc/rustic)
  • rustic_config_content: Required. Full TOML configuration content for rustic

The role uses rustic's TOML config file approach. You provide the complete configuration as a YAML multiline string, and the role will write it to /etc/rustic/rustic.toml.

See the rustic configuration documentation for all available options.

Repository initialization

The role automatically handles repository initialization:

  • Checks if the repository exists by running rustic snapshots
  • If the repository doesn't exist, runs rustic init automatically
  • Sets compression level to 7 with rustic config --set-compression 7

Systemd service and timer

A rustic-backup.service service will be created that runs rustic backup. The service is of type oneshot and will be triggered periodically with rustic-backup.timer.

The timer schedule can be configured with:

  • rustic_timer_on_calendar: defines the OnCalendar directive (default: "*-*-* 03:42:00" = daily at 3:42 AM)

See the systemd.timer documentation for more information.

You can see the logs of the backup with journalctl:

journalctl -xefu rustic-backup

Example playbook

Basic example with local repository

---
- hosts: myserver
  roles:
    - role: rustic
      vars:
        rustic_timer_on_calendar: "*-*-* 02:30:00"  # Run at 2:30 AM
        rustic_config_content: |
          [repository]
          repository = "/backup/repo"
          password = "mysuperduperpassword"

          [forget]
          keep-daily = 7

          [[backup.snapshots]]
          name = "default"
          sources = ["/home", "/etc", "/var/log"]

Example with S3 backend

---
- hosts: myserver
  roles:
    - role: rustic
      vars:
        rustic_timer_on_calendar: "*-*-* 02:30:00"  # Run at 2:30 AM
        rustic_config_content: |
          [repository]
          repository = "opendal:s3"
          password = "mysuperduperpassword"

          [repository.options]
          bucket = "my-backup-bucket"
          endpoint = "https://s3.amazonaws.com"
          region = "us-east-1"
          access_key_id = "XXXXX"
          secret_access_key = "XXXXX"

          [forget]
          keep-daily = 7
          prune = true

          [[backup.snapshots]]
          sources = ["/home", "/var/www", "/etc"]

Example with database dumps using hooks

This example shows how to use rustic hooks to dump a database before backup and clean up the dump file afterwards.

---
- hosts: myserver
  roles:
    - role: rustic
      vars:
        rustic_config_content: |
          [repository]
          repository = "/backup/repo"
          password = "mysuperduperpassword"

          [backup.hooks]
          run-before = [
            "mkdir -p /var/backups/dumps",
            "sudo -u postgres pg_dump -Fc mydb -f /var/backups/dumps/mydb.dump"
          ]
          run-finally = [
            "rm -f /var/backups/dumps/mydb.dump"
          ]

          [[backup.snapshots]]
          name = "default"
          sources = ["/var/backups/dumps", "/etc"]

For MySQL/MariaDB, you can use similar hooks:

[backup.hooks]
run-before = [
  "mkdir -p /var/backups/dumps",
  "mysqldump --single-transaction mydb -r /var/backups/dumps/mydb.sql"
]

See the rustic hooks documentation for more advanced hook configurations.

Managing backups

After the role is applied, you can interact with rustic using the config file:

# View snapshots
rustic snapshots

# Run manual backup
systemctl start rustic-backup

# Check timer status
systemctl status rustic-backup.timer

# View next scheduled run
systemctl list-timers rustic-backup.timer

Security Considerations

This role implements several security best practices:

File Permissions

  • Config directory (/etc/rustic): 0700 (only root can access)
  • Config file (/etc/rustic/rustic.toml): 0600 (only root can read/write)
  • Binary (/usr/local/bin/rustic): 0755 (executable by all, writable only by root)

The config file contains sensitive data (repository passwords, cloud credentials) and is protected with restrictive permissions.

Systemd Service Hardening

The systemd service includes security hardening features:

  • ProtectSystem=strict: Makes system directories read-only
  • ProtectHome=read-only: Protects home directories (allows read for backup)
  • PrivateTmp=true: Provides isolated /tmp directory
  • NoNewPrivileges=true: Prevents privilege escalation
  • PrivateDevices=true: Restricts device access

Best Practices

  • Use ansible-vault: Store rustic_config_content in an encrypted vault file to protect credentials
  • Principle of least privilege: The service runs as root (required for full system backup), but with systemd restrictions
  • Regular updates: Using rustic_version: "latest" ensures you get security updates automatically

Example using ansible-vault:

ansible-vault create vars/rustic-secrets.yml
# Add: rustic_config_content: |
#        [repository]
#        password = "secret"

License

MIT

About

A simple Ansible role to set up Rustic (Restic-compatible) ⚠️ Work in Progress

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages