15

I am trying to add nodev to my /etc/fstab file. I am using the Ansible command below but with no luck. My issue lies with the regular expression, I'm not a pro at regex.

- name: Add nodev to /etc/fstab
  lineinfile:
    dest=/etc/fstab
    backup=yes
    backrefs=yes
    state=present
    regexp='(^/dev[\w/_-]+(\s+(?!nodev)[\w,]+)*)'
    line='\1,nodev'

One of the lines from /etc/fstab that I am trying to add nodev is:

/dev/mapper/ex_sys-ex_home /home /ext4 rw,exec,auto,nouser,sync 1 2
Ayman Nedjmeddine
  • 11,521
  • 1
  • 20
  • 31
Brian Putt
  • 1,288
  • 2
  • 15
  • 33
  • 1
    Define "no luck". What was the actual result? I'm guessing that /etc/fstab was unchanged, instead of adding "nodev" to some lines? – LarsH Sep 22 '14 at 15:15
  • @LarsH will provide results here in a second, I modified the regexp to (^/dev[\w/_-]+\s+/[\w/_-]+\s+/[\w/_-]+\s+((?!nodev)[\w,]+)*) and I think that might work – Brian Putt Sep 22 '14 at 15:18
  • Yeah, I think the fact that you had `\s+` in your repeating group for the options was blocking the match. Let me know if it didn't work. – LarsH Sep 22 '14 at 15:22
  • The regexp before was adding nodev to a swap drive(one of the one's I didn't want it to be added to)....applying the new regex doesn't modify anything. Removing the \s+ only added it to one of the mapper drives(at the end of the string, not where it needed to go) – Brian Putt Sep 22 '14 at 15:36

7 Answers7

26

While this may not be the most elegant answer, it worked for me.

- name: Ensure fstab uses nodev
  mount:
    name: "{{ item.mount }}"
    src: "{{ item.device }}"
    fstype: "{{ item.fstype }}"
    opts: "{{ item.options }},nodev"
    state: present
  with_items: ansible_mounts
  when: item.options.find(",") >= 0 and item.options.find("nodev") == -1
Brian Putt
  • 1,288
  • 2
  • 15
  • 33
  • Actually I find it very nice and concise. – jojeck Apr 01 '16 at 15:00
  • 2
    Thanks For this I needed to only edit some mount paths, so I added a list (mnt_paths) of the paths. and then added additional conditional to say when `item.mount in mnt_paths` to be more targeted. – Josh Beauregard Feb 27 '19 at 18:32
  • 3
    Not sure if this depends on the version but in ansible 2.4.2.0 I have to use `with_items: "{{ ansible_mounts }}"` instead. – Bram May 09 '19 at 14:52
  • 3
    The problem with this approach is that it may incorporate temporary mounts into the static `/etc/fstab`, and also it will change some items for the less stable variants, like *UUID* references into dynamic `/dev/mapper/*` paths – Alexander Shcheblikin Nov 28 '19 at 09:40
  • I made too changes. The first one is the same as comment from Bram above. `with_items: "{{ ansible_mounts }}"` and second is to add `when: item.mount == "/" and item.options.find(",") >= 0 and item.options.find("nodev") == -1` – AngularNerd Jan 16 '23 at 19:37
8

Inspired by Joe's answer I made this version which will add a single option to a specific line in /etc/fstab if it isn't there already. This will also keep any other options the line already had.

main.yml

- import_tasks: fstab-opt-present.yml point=/home opt=nodev

fstab-opt-present.yml

- name: '/etc/fstab: Set opt "{{ opt }}" for mount point {{ point }}'
  lineinfile:
    path: /etc/fstab
    backup: yes
    backrefs: yes
    regexp: '^(\S+\s+{{ point }}\s+\S+\s+)(?!(?:\S*,)?{{ opt }}(?:,\S*)?\s+)(\S+)(\s+.+)$'
    line: '\1{{ opt }},\2\3'
  register: fstab

- name: 'If {{ point }} changed, remount'
  command: 'mount {{ point }} -o remount'
  when: fstab.changed

https://regex101.com/ is a really helpful tool for building and testing these kind of regexps. Just enable the "multiline" option there and open the "Substitution" panel and you can even paste in your /etc/fstab and see which lines your regex will match and what it will do to them. Just remember to use real values instead of the Ansible variables {{ point }} etc. when testing there

Haprog
  • 793
  • 1
  • 9
  • 21
  • 1
    `validate: "mount -fav -T%s"` is a nice option to add. It basically does a dry run of `mount -a` for the new file. – Thomas Sep 10 '21 at 13:57
4

I wanted to state that there seems to be a new ansible module which covers all this much more easily: https://docs.ansible.com/ansible/latest/modules/mount_module.html

  • 2
    A link to a solution is welcome, but please ensure your answer is useful without it: [add context around the link](https://meta.stackexchange.com/a/8259) so your fellow users will have some idea what it is and why it’s there, then quote the most relevant part of the page you're linking to in case the target page is unavailable. [Answers that are little more than a link may be deleted](https://stackoverflow.com/help/deleted-answers). – brass monkey Apr 05 '19 at 08:46
3

We've developed a 3rd-party ansible module to add, set or remove mount options. Check it out!

  - mountopts:
      name: /
      option: nodev

https://github.com/Uberspace/ansible-mountopts

luto
  • 140
  • 2
  • 9
2

Tested & works fine

- name: Set  nodev option
  replace:
    path: /etc/fstab
    backup: yes
    regexp: '^(\S+\s+)(\/\S+)(\s+)((?:ext4|xfs)\s+)(?!(?:\S*,)?nodev(?:,\S*)?\s+)(\S+)(\s+.+)$'
    replace: '\1\2 \4 \5,nodev \6'

It excludes adding nodev to /(root), sets only to ext4 and xfs filesystem. doesn't add to temp filesystems.

Note: while you test regexp101, make sure to select python

amphetamachine
  • 27,620
  • 12
  • 60
  • 72
Rajesh
  • 21
  • 1
0

Landed here looking for an answer, wound up rolling my own for my use case:

main.yml

- include: fstab-opts.yml point=/tmp opts=noexec,nodev,nosuid,noatime
- include: fstab-opts.yml point=/backup opts=noatime

fstab-opts.yml

---

- name: 'Ensure {{ point }} flags'
  lineinfile:
    path: /etc/fstab
    # uses "(not-spaces spaces /tmp spaces )(not-spaces)(the rest)" pattern to match column content and capture args
    regexp: '^([^ ]+[ ]+\{{ point }}[ ]+[^ ]+[ ]+)([^ ]+)(.*)'
    line: '\1{{ opts }}\3'
    backrefs: yes
  register: fstab

- name: 'If {{ point }} changed, remount'
  command: mount -o remount {{ point }}
  when: fstab.changed
Abizern
  • 146,289
  • 39
  • 203
  • 257
Joe Still
  • 141
  • 1
  • 4
0

i have added the noexec,nodev,nosuid option in /etc/fstab for the /var/tmp mount point.

Requirement is:

  1. Ensure noexec option set on /var/tmp partition
  2. Ensure nodev option set on /var/tmp partition
  3. Ensure nosuid option set on /var/tmp partition

if required install ansible.posix.mount module using below command .

# ansible-galaxy collection install ansible.posix

Playbook:

---
 - name: "STEP 1: Get /var/tmp mounted SRC device"
   shell: mount | grep -E '\s/var/tmp\s' | awk '{print $1}'
   register: "vartmpsrc"

 - debug:
     msg: "Validated the /var/tmp mount output: {{ vartmpsrc.stdout }}"

 - name: "Add mount noexec,nodev,nosuid options for /var/tmp"
   mount:
     path: "/var/tmp"
     src: "{{ vartmpsrc.stdout }}"
     fstype: "tmpfs"
     opts: "nosuid,nodev,noexec"
     state: "present"
   when: vartmpsrc.stdout == "/var/tmp"

 - name: Remount /var/tmp mounted volume with mount options noexec,nodev,nosuid
   ansible.posix.mount:
    path: /var/tmp
    state: remounted
   when: vartmpsrc.stdout == "/var/tmp"

 - name: 'STEP 2: Validate noexec,nodev,nosuid option set on /var/tmp partition'
   shell: mount | grep -E '\s/var/tmp\s' | grep -v {{ item }}
   loop:
    - noexec
    - nodev
    - nosuid
   register: vartmp_exists
   ignore_errors: yes
   when: vartmpsrc.stdout == "/var/tmp"
amphetamachine
  • 27,620
  • 12
  • 60
  • 72