NAS Mount Systemd
This role manages CIFS/SMB network share mounting using systemd mount units instead of traditional /etc/fstab entries.
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
| Variable | Required | Description |
|---|---|---|
nas_mount_systemd_mounts | Yes | List 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:
| Field | Required | Default | Description |
|---|---|---|---|
name | Yes | - | Unique identifier for mount |
server | Yes | - | NAS IP address or hostname |
share | Yes | - | Share path on NAS |
mount_point | Yes | - | Local mount directory |
user | Yes | - | CIFS username |
password | Yes | - | Password (from vault) |
domain | Yes | - | Windows domain or workgroup |
file_mode | No | 0644 | File permissions on mount |
dir_mode | No | 0755 | Directory permissions on mount |
state | Yes | - | 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
-
Installs cifs-utils package
- Required for CIFS/SMB mounting
-
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
- Creates mount point directory (e.g.,
When state = absent
- 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 Point | Unit File Name |
|---|---|
/mnt/synology | mnt-synology.mount |
/mnt/synology/media | mnt-synology-media.mount |
/media/nas/backups | media-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 descriptionRequires: Wait for network to be onlineAfter: Mount after network is available
[Mount]:
What: UNC path to NAS shareWhere: Local mount pointOptions: CIFS mount optionsType: 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 read0600: Owner read/write only
dir_mode: Permissions for directories on mount
0755: Owner full, others read/execute (default)0750: Owner full, group read/execute0700: 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.targetstatus - 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/nasbetter 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
- Use descriptive mount names (matches NAS purpose)
- Store passwords in Ansible Vault (never plaintext)
- Configure appropriate file_mode/dir_mode (least privilege)
- Monitor mount status with systemctl
- Review logs regularly (journalctl for errors)
- Test unmount/remount after configuration changes
- Use network-online dependency (already configured)
- Document mount purposes in unit descriptions
- Clean up unused mounts (state: absent)
- Backup credential files (part of /etc backup)
Comparison with nas_mount Role
| Feature | nas_mount (fstab) | nas_mount_systemd |
|---|---|---|
| Method | /etc/fstab | Systemd mount units |
| Network wait | Manual (_netdev option) | Built-in (network-online.target) |
| Service control | Limited | Full systemctl support |
| Parallel mount | No | Yes |
| Logging | Limited | journalctl integration |
| Status check | mount command | systemctl status |
| Per-mount management | Edit fstab | Independent services |
| Modern approach | Legacy | Systemd native |
When to use nas_mount: Legacy systems, simple setups When to use nas_mount_systemd: Modern systems, complex setups, better monitoring
Related Roles
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.