Combine with_items loop with vars

4,454 views
Skip to first unread message

stephan....@gmail.com

unread,
Aug 2, 2014, 3:05:07 AM8/2/14
to ansible...@googlegroups.com
Friends,

I'd like to iterate over ansible_mounts and set custom options for /some/ mount points, like so

/var: defaults,nosuid
/home: defaults,nosuid,nodev
/: defaults

- name: Secure Mount options
  mount: name={{ item.mount }} src='{{ item.device }}' state=present fstype={{ item.fstype }} opts={{ ??? }}
  with_items: ansible_mounts

How can I combine the list of vars within my loop. So that opts= is filled with the value looked up depending on the mount point?

Thanks for any pointers!
Stephan

Amr Ali

unread,
Aug 2, 2014, 1:09:31 PM8/2/14
to ansible...@googlegroups.com
you need to use with_dict instead of with_items 

so you vars declaration would look like :

---
ansible_mounts
:
    mount1
:
      mount
: /some/mount/point
      device
: some_device
      fstype
: some_type
     opts
: "some options here"
    mount2
:
      mount
: /another/mount/point
      device
: another_device
      fstype
: another_type
     opts
: "some other options here"



And your task would look like :

- name: Secure Mount options

  mount
: name={{ item.mount }} src='{{ item.device }}' state=present fstype={{ item.fstype }} opts={{ item.opts }}
  with_dict
: ansible_mounts




stephan....@gmail.com

unread,
Aug 4, 2014, 12:19:54 PM8/4/14
to ansible...@googlegroups.com
Hi!

Thanks for your help. I'm still not getting it kinda, but my initial post wasn't really clearly formulated actually.

I actually like to iterate over the ansible_mounts object fact that has three mount points. And then use those facts to build my mount tasks, except for the mount options, which I'd like to specify myself. So in (broken) shell like pseudo code that would be something like:

for i in ansible_mounts; do
  task = "
mount: name={{ ansible_mount.mount }} src={{ ansible_mount.device }} state=present fstype={{ ansible:mount.fstype }}"
  if ansible_mount.mount -eq '/var'
    opts={{ defaults,nosuid }}
  elseif ansible_mount.mount -eq '/home'
    opts={{ defaults,nosuid,nodev }}
  fi
done

That way, I could specify the mount options dynamically, no matter how many devices are actually present in ansible.mounts. My current solution is rather static, using with_items like so - and requires labels to be set:


- name: Secure Mount options
  mount: name={{ item.mount }} src='LABEL={{ item.label }}'
         state=present fstype={{ item.fs }}
         opts={{ item.options }} passno={{ item.fsck }}
  with_items:
     - { mount: '/home', label: 'home', fs: 'ext4', fsck: '2', options: 'defaults,nosuid,nodev' }
     - { mount: '/var', label: 'var', fs: 'ext4', fsck: '2', options: 'defaults,nosuid' }
     - { mount: '/', label: 'root', fs: 'ext4', fsck: '1', options: 'defaults' }
     - { mount: 'swap', label: 'swap', fs: 'swap', fsck: '0', options: 'defaults' }

Is that possible?
Cheers,
Stephan

Amr Ali

unread,
Aug 4, 2014, 9:48:08 PM8/4/14
to ansible...@googlegroups.com
Hi,

didn't realize you were using the ansible_mounts fact, i understand what you are trying to do here and i think there might be a way..

how about you try doing this :

Define a new  var "mount_options" which links mount names to options predefined by you, then use it in your mount command to dynamically fill the options argument.

what i mean is this..

---
- hosts: all
  gather_facts
: no
  vars
:
   
-  mount_options:
       
"/home": "defaults"
       
"/var": "defaults,nosuid"
       
"/": "defaults"
  tasks
:
   
- name: Secure Mount options
     mount
: name={{ item.mount }} src='{{ item.device }}' state=present fstype={{ item.fstype }} opts={{ mount_options[item.mount] }}
     with_items
: ansible_mounts
     
when: mount_options[item.mount] is defined

this should work for you, all you need is define all your possible mount -> mount options in that variable "mount_options", the when conditional statement at the end is important, so it won't fail if it encounters a mount that doesn't have options set by you in the "mount_options" variable.

here is what i used to test that this concept actually works :

---
- hosts: all
  gather_facts
: no
  vars
:
   
-  mount_options:
       
"/home": "defaults"
       
"/var": "defaults,nosuid"
       
"/": "defaults"
  tasks
:
   
- name: test vars
      debug
: msg="{{ item.mount }} and {{ mount_options[item.mount] }}"
      with_items
:
       
- { mount: '/home', fs: 'ext4'}
       
- { mount: '/var', fs: 'ext4'}
       
- { mount: '/', fs: 'ext4'}
       
- { mount: 'swap', fs: 'swap'}
     
when: mount_options[item.mount] is defined



Amr Ali

unread,
Aug 4, 2014, 9:55:27 PM8/4/14
to ansible...@googlegroups.com
actually you might also want to do it this way

---
- hosts: all
  gather_facts
: no
  vars
:
   
-  mount_options:
       
"/home": "defaults"
       
"/var": "defaults,nosuid"
       
"/": "defaults"
  tasks
:

   
- name: Secure Mount options
     mount
: name={{ item.mount }} src={{ item.device }} state=present fstype={{ item.fstype }} opts={{ mount_options[item.mount] | default(item.options) }}
     with_items
: ansible_mounts

what i did here is drop the "when" check and instead used default filter so it'd fallback to the default mount options if it didn't find options for that specific mount in your "mount_options" variable, both examples are usable and depends on your use case. 

Good luck


On Saturday, August 2, 2014 9:05:07 AM UTC+2, stephan....@gmail.com wrote:

stephan....@gmail.com

unread,
Aug 5, 2014, 11:42:18 AM8/5/14
to ansible...@googlegroups.com
Awesome! This works like a charme.

Thanks a lot!
Stephan
Reply all
Reply to author
Forward
0 new messages