NAS Mount Systemd

This role manages CIFS/SMB network share mounting using systemd mount units instead of traditional /etc/fstab entries.

ARA Ansible Bash DHCP Docker NAS SMB Synology

NAS Mount Systemd Role

Overview

This role manages CIFS/SMB network share mounting using systemd mount units instead of traditional /etc/fstab entries. It installs cifs-utils, creates mount point directories, generates secure credential files, creates systemd .mount unit files with proper dependencies, enables and starts mount units, and handles automatic mounting with better integration into systemd service management.

Purpose

  • Systemd Integration: Mount management via systemd units
  • Better Dependencies: Wait for network before mounting
  • Service Control: Use systemctl to manage mounts
  • Automatic Retry: Built-in retry logic on mount failures
  • Status Monitoring: Check mount status with systemctl
  • Clean State Management: Enable/disable mounts as services
  • Parallel Mounting: Systemd can mount multiple shares in parallel
  • Modern Approach: Native systemd integration vs legacy fstab

Requirements

  • Ansible 2.9 or higher
  • Systemd-based Linux distribution
  • NAS devices accessible via network
  • CIFS/SMB shares configured on NAS
  • NAS user accounts with appropriate permissions
  • Ansible Vault for storing NAS passwords
  • Proper sudo/root permissions on target host

Systemd Mount Units vs /etc/fstab

Traditional /etc/fstab Approach

  • Mounts processed sequentially at boot
  • Limited retry logic
  • No service dependencies
  • Hard to manage mount failures
  • All mounts in single configuration file

Systemd Mount Units (This Role)

  • Each mount is a systemd service
  • Parallel mounting for better boot performance
  • Built-in network dependency (waits for network-online.target)
  • Easy service management (start, stop, restart, status)
  • Automatic retry on failure
  • Better logging (journalctl)
  • Independent mount management

Role Variables

Required Variables

VariableRequiredDescription
nas_mount_systemd_mountsYesList of NAS mount configurations

Variable Details

nas_mount_systemd_mounts

List of NAS mounts to configure as systemd units.

Structure:

nas_mount_systemd_mounts:
  - name: mount_identifier
    server: nas_ip_address
    share: /share_path
    mount_point: /local/mount/point
    user: nas_username
    password: "{{ vault_password }}"
    domain: WORKGROUP
    file_mode: "0644"
    dir_mode: "0755"
    state: present

Example configuration:

nas_mount_systemd_mounts:
  - name: synology-media
    server: "192.168.x.x"
    share: "/Media"
    mount_point: "/mnt/synology/media"
    user: "mediauser"
    password: "{{ vault_synology_media_password }}"
    domain: "WORKGROUP"
    file_mode: "0644"
    dir_mode: "0755"
    state: present

  - name: qnap-backups
    server: "192.168.x.x"
    share: "/Backups"
    mount_point: "/mnt/qnap/backups"
    user: "backupuser"
    password: "{{ vault_qnap_backup_password }}"
    domain: "WORKGROUP"
    file_mode: "0640"
    dir_mode: "0750"
    state: present

Field descriptions:

FieldRequiredDefaultDescription
nameYes-Unique identifier for mount
serverYes-NAS IP address or hostname
shareYes-Share path on NAS
mount_pointYes-Local mount directory
userYes-CIFS username
passwordYes-Password (from vault)
domainYes-Windows domain or workgroup
file_modeNo0644File permissions on mount
dir_modeNo0755Directory permissions on mount
stateYes-present to mount, absent to unmount

Unmounting example:

nas_mount_systemd_mounts:
  - name: old-nas
    mount_point: "/mnt/old-nas"
    state: absent

Dependencies

This role has no dependencies on other Ansible roles, but requires:

  • Package: cifs-utils (installed by role)
  • Systemd-based Linux distribution
  • NAS devices accessible on network
  • Ansible Vault for storing passwords

Example Playbook

Basic Usage

---
- name: Mount NAS via Systemd
  hosts: media_server
  become: true

  vars:
    nas_mount_systemd_mounts:
      - name: synology-media
        server: "192.168.x.x"
        share: "/Media"
        mount_point: "/mnt/synology/media"
        user: "mediauser"
        password: "{{ vault_synology_password }}"
        domain: "WORKGROUP"
        file_mode: "0644"
        dir_mode: "0755"
        state: present

  roles:
    - nas_mount_systemd

Multiple NAS Mounts

---
- name: Mount Multiple NAS Shares
  hosts: backup_server
  become: true

  vars:
    nas_mount_systemd_mounts:
      - name: synology-backups
        server: "192.168.x.x"
        share: "/Backups"
        mount_point: "/mnt/synology/backups"
        user: "backupuser"
        password: "{{ vault_synology_backup_password }}"
        domain: "WORKGROUP"
        file_mode: "0644"
        dir_mode: "0755"
        state: present

      - name: qnap-archives
        server: "192.168.x.x"
        share: "/Archives"
        mount_point: "/mnt/qnap/archives"
        user: "archiveuser"
        password: "{{ vault_qnap_archive_password }}"
        domain: "WORKGROUP"
        file_mode: "0644"
        dir_mode: "0755"
        state: present

  roles:
    - nas_mount_systemd

Unmount NAS Share

---
- name: Unmount NAS Share
  hosts: media_server
  become: true

  vars:
    nas_mount_systemd_mounts:
      - name: old-nas
        server: "192.168.x.x"
        share: "/OldShare"
        mount_point: "/mnt/old-nas"
        user: "user"
        password: "{{ vault_old_password }}"
        domain: "WORKGROUP"
        state: absent

  roles:
    - nas_mount_systemd

With Custom Permissions

---
- name: Mount NAS with Restricted Permissions
  hosts: secure_server
  become: true

  vars:
    nas_mount_systemd_mounts:
      - name: secure-nas
        server: "192.168.x.x"
        share: "/Secure"
        mount_point: "/mnt/secure"
        user: "secureuser"
        password: "{{ vault_secure_password }}"
        domain: "WORKGROUP"
        file_mode: "0600"  # Owner only read/write
        dir_mode: "0700"   # Owner only access
        state: present

  roles:
    - nas_mount_systemd

What This Role Does

When state = present

  1. Installs cifs-utils package

    • Required for CIFS/SMB mounting
  2. For each mount:

    • Creates mount point directory (e.g., /mnt/synology/media)
    • Creates credentials file (/etc/nas_creds_{name}_systemd) with mode 0600
    • Generates systemd .mount unit in /lib/systemd/system/
    • Enables mount unit (starts on boot)
    • Starts mount unit (mounts immediately)
    • Restarts if credentials changed

When state = absent

  1. For each mount:
    • Stops mount unit (unmounts share)
    • Disables mount unit (won’t mount on boot)
    • Removes .mount unit file
    • Deletes credentials file
    • Removes mount point directory
    • Reloads systemd daemon

Systemd Mount Unit Files

Unit File Naming

Systemd mount units are named based on mount point:

Mount PointUnit File Name
/mnt/synologymnt-synology.mount
/mnt/synology/mediamnt-synology-media.mount
/media/nas/backupsmedia-nas-backups.mount

Rule: Remove leading /, replace / with -, add .mount extension

Unit File Location

Mount units are placed in:

/lib/systemd/system/mnt-synology-media.mount

Unit File Content

Example generated unit file:

[Unit]
Description=Mount synology-media - //192.168.x.x/Media
Requires=network-online.target
After=network-online.target

[Mount]
What=//192.168.x.x/Media
Where=/mnt/synology/media
Options=credentials=/etc/nas_creds_synology-media_systemd,file_mode=0644,dir_mode=0755
Type=cifs

[Install]
WantedBy=multi-user.target

Sections explained:

[Unit]:

  • Description: Human-readable mount description
  • Requires: Wait for network to be online
  • After: Mount after network is available

[Mount]:

  • What: UNC path to NAS share
  • Where: Local mount point
  • Options: CIFS mount options
  • Type: Filesystem type (cifs)

[Install]:

  • WantedBy: Enable for multi-user target (normal boot)

Systemd Service Management

Check Mount Status

# Check specific mount
systemctl status mnt-synology-media.mount

# List all mount units
systemctl list-units --type=mount

# Check if enabled
systemctl is-enabled mnt-synology-media.mount

# Check if active
systemctl is-active mnt-synology-media.mount

Manual Mount Operations

# Start (mount)
systemctl start mnt-synology-media.mount

# Stop (unmount)
systemctl stop mnt-synology-media.mount

# Restart (remount)
systemctl restart mnt-synology-media.mount

# Enable (mount on boot)
systemctl enable mnt-synology-media.mount

# Disable (don't mount on boot)
systemctl disable mnt-synology-media.mount

View Mount Logs

# View logs for specific mount
journalctl -u mnt-synology-media.mount

# Follow logs in real-time
journalctl -u mnt-synology-media.mount -f

# View recent logs
journalctl -u mnt-synology-media.mount -n 50

# View logs since boot
journalctl -u mnt-synology-media.mount -b

Credential Files

Format

Role creates credential files at /etc/nas_creds_{name}_systemd:

username=mediauser
password=secret_password
domain=WORKGROUP

Security

  • Location: /etc/nas_creds_synology-media_systemd
  • Permissions: 0600 (owner read/write only)
  • Ownership: root:root
  • Purpose: Secure password storage

Credentials Change Handling

Role automatically detects credential changes and restarts mount:

  • Updates credential file
  • Registers change
  • Restarts systemd mount unit
  • New credentials applied immediately

File and Directory Permissions

file_mode and dir_mode

These options control permissions on mounted filesystem:

file_mode: Permissions for files on mount

  • 0644: Owner read/write, others read (default)
  • 0640: Owner read/write, group read
  • 0600: Owner read/write only

dir_mode: Permissions for directories on mount

  • 0755: Owner full, others read/execute (default)
  • 0750: Owner full, group read/execute
  • 0700: Owner full access only

Example for secure mount:

file_mode: "0600"  # Only owner can read/write files
dir_mode: "0700"   # Only owner can access directories

Example for shared mount:

file_mode: "0664"  # Owner and group can read/write
dir_mode: "0775"   # Owner and group full access

Network Dependencies

Systemd mount units wait for network before mounting:

Requires=network-online.target
After=network-online.target

Benefits:

  • Prevents mount failures during boot
  • Waits for network interface to be ready
  • Handles DHCP address acquisition
  • Better than racing with network initialization

If network is slow, mount may timeout. Check:

systemctl status network-online.target

Advantages Over /etc/fstab

Systemd Mount Units

✅ Individual service per mount ✅ Built-in network dependency ✅ Parallel mounting ✅ Better error handling and retry ✅ Easy status checking (systemctl status) ✅ Detailed logging (journalctl) ✅ Service integration (dependencies) ✅ Can mount/unmount without editing config

Traditional /etc/fstab

❌ All mounts in one file ❌ No automatic network waiting ❌ Sequential mounting ❌ Limited error reporting ❌ Must edit file to change mounts ❌ Harder to debug failures

Verifying Mounts

Check Active Mounts

# List all systemd mounts
systemctl list-units --type=mount | grep mnt

# Check specific mount
systemctl status mnt-synology-media.mount

# Verify files accessible
ls -la /mnt/synology/media/

Check Mount Options

# View current mount options
mount | grep cifs

# Should show:
# //192.168.x.x/Media on /mnt/synology/media type cifs (...)

Check Unit Files

# List mount unit files
ls -l /lib/systemd/system/*.mount

# View specific unit
cat /lib/systemd/system/mnt-synology-media.mount

# Check unit syntax
systemd-analyze verify mnt-synology-media.mount

Test Read/Write

# Test read
ls /mnt/synology/media/

# Test write (permissions dependent)
touch /mnt/synology/media/test_file.txt
echo "test" > /mnt/synology/media/test_file.txt
rm /mnt/synology/media/test_file.txt

Security Considerations

  • Credential Files: Protected with mode 0600 (root only)
  • Passwords in Vault: Never in plaintext
  • No Logging: Tasks marked with no_log: true
  • Root Ownership: Credentials owned by root:root
  • File Permissions: Configurable file_mode and dir_mode
  • Systemd Integration: Benefits from systemd security features
  • Network Security: CIFS traffic not encrypted (consider VPN)

Tags

This role does not define any tags. Use playbook-level tags if needed:

- hosts: media_server
  roles:
    - nas_mount_systemd
  tags:
    - nas
    - mount
    - systemd
    - storage

Notes

  • Role uses systemd mount units (not /etc/fstab)
  • Each mount is an independent systemd service
  • Unit files placed in /lib/systemd/system/
  • Credentials stored in /etc/nas_creds_{name}_systemd
  • Supports per-mount file/directory permissions
  • Automatic credential change detection
  • Network dependency built-in (network-online.target)
  • Role is idempotent (safe to run multiple times)

Troubleshooting

Mount unit fails to start

Check status:

systemctl status mnt-synology-media.mount
journalctl -u mnt-synology-media.mount -n 50

Common issues:

  • Network not ready: Check network-online.target status
  • Invalid credentials: Verify /etc/nas_creds_{name}_systemd
  • NAS unreachable: Ping NAS server
  • Mount point already in use: Check if directory has files

”mount.cifs: Permission denied”

Cause: Invalid credentials

Solution:

# Check credentials file
cat /etc/nas_creds_synology-media_systemd

# Test credentials manually
smbclient //nas-ip/share -U username

# Update password in vault and re-run role

Mount unit won’t enable

Check unit file:

# Verify unit file syntax
systemd-analyze verify mnt-synology-media.mount

# Check for typos in unit file
cat /lib/systemd/system/mnt-synology-media.mount

# Reload systemd
systemctl daemon-reload

Mount point name conflicts

Cause: Mount point path creates invalid unit name

Solution: Systemd has naming restrictions:

  • Use simple paths: /mnt/nas better than /mnt/my-nas-shares
  • Avoid special characters in mount point names
  • Keep paths short and simple

Network dependency not working

Check network-online.target:

systemctl status network-online.target

# If inactive, enable wait-online service:
systemctl enable systemd-networkd-wait-online.service

Credentials changed but mount not restarted

Force restart:

systemctl restart mnt-synology-media.mount

# Or re-run Ansible role
ansible-playbook site.yml --tags nas

Can’t unmount (device busy)

Cause: Files in use on mount

Solution:

# Check what's using mount
lsof +D /mnt/synology/media/

# Kill processes if needed
# Then stop mount:
systemctl stop mnt-synology-media.mount

Testing After Role Execution

Verify Systemd Units Created

# List mount units
systemctl list-unit-files --type=mount | grep mnt

# Should show your mount units

Verify Units Enabled and Active

# Check enabled status
systemctl is-enabled mnt-synology-media.mount
# Should output: enabled

# Check active status
systemctl is-active mnt-synology-media.mount
# Should output: active

Test Mount Persistence

# Reboot system
reboot

# After reboot, check mount status
systemctl status mnt-synology-media.mount
# Should be active (mounted)

# Verify files accessible
ls /mnt/synology/media/

Test Manual Operations

# Unmount
systemctl stop mnt-synology-media.mount

# Verify unmounted
mount | grep synology
# Should show nothing

# Remount
systemctl start mnt-synology-media.mount

# Verify mounted
mount | grep synology
# Should show mount

Performance Considerations

  • Parallel Mounting: Systemd mounts shares in parallel for faster boot
  • Network Dependency: May add slight delay waiting for network
  • Retry Logic: Built-in retries can increase mount time on failures
  • Logging Overhead: Journald logs add minimal overhead

Best Practices

  1. Use descriptive mount names (matches NAS purpose)
  2. Store passwords in Ansible Vault (never plaintext)
  3. Configure appropriate file_mode/dir_mode (least privilege)
  4. Monitor mount status with systemctl
  5. Review logs regularly (journalctl for errors)
  6. Test unmount/remount after configuration changes
  7. Use network-online dependency (already configured)
  8. Document mount purposes in unit descriptions
  9. Clean up unused mounts (state: absent)
  10. Backup credential files (part of /etc backup)

Comparison with nas_mount Role

Featurenas_mount (fstab)nas_mount_systemd
Method/etc/fstabSystemd mount units
Network waitManual (_netdev option)Built-in (network-online.target)
Service controlLimitedFull systemctl support
Parallel mountNoYes
LoggingLimitedjournalctl integration
Status checkmount commandsystemctl status
Per-mount managementEdit fstabIndependent services
Modern approachLegacySystemd native

When to use nas_mount: Legacy systems, simple setups When to use nas_mount_systemd: Modern systems, complex setups, better monitoring

This role is often used with:

  • nas_mount: Alternative using /etc/fstab
  • docker_data_backup: Backup Docker data to NAS
  • ansible_code_backup: Backup Ansible code to NAS

License

MIT

Author

Created for homelab infrastructure management.