Fearthepenguin.net

Diary of a Lazy SysAdmin

Skip to: Content | Sidebar | Footer

Saltstack: Set ACLs on files or directories

I found it difficult to work out exactly how to do this. I initially thought to use salt.states.linux_acl but it is severely limited, so I had to look elsewhere.

Specific salt.states.linux.acl issues
  1. Can set default acl using: “acl_type: ‘d:group’  ” but it is not documented at all.
  2. Can’t use ‘rwX’ [to make only dirs executable] as perms as it doesn’t understand ‘X’ at all.

 

The items needed are documented but it’s not super clear how to put them together, so that’s what I’m showing now.

Goal:

To create a directory then set an active ACL as well as a default ACL on it.
In this case we are looking to create:
/usr/local/mydir
Owned by ‘myuser’ and ‘mygroup’
And give the ‘othergroup’ permission to read/write/execute dirs, and read/write any files created under it.

At the command line this would have been done by running three commands:

mkdir /usr/local/mydir
setfacl -d -m g:othergroup:rwX /usr/local/mydir
setfacl -m g:othergroup:rwX /usr/local/mydir

You could just use salt’s cmd.run to do this but that’s not very salt-like so we want to do it in a state.

 

Requirements:

salt.modules.linux_acl.modfacl
salt.states.module

Solution

So to do this we have to use salt.states.module to call salt.modules.linux_acl.modfacl since the module can’t be directly run in a state, and the  salt.states.linux_acl sucks. 

init.sls [state]


/usr/local/mydir:
  file.directory:
  - user: myuser
  - group: mygroup
  - dir_mode: 755
  - makedirs: True
  - require:
    - user: myuser
    - group: mygroup
usr_local_mydir_defaultacl:
  module.run:
  - name: acl.modfacl
  - acl_type: 'default:group'
  - acl_name: othergroup
  - perms: rwX
  - args:
    - /usr/local/mydir
  - require:
    - group: othergroup
    - file:/usr/local/mydir
usr_local_mydir_activeacl:
  module.run:
  - name: acl.modfacl
  - acl_type: 'group'
  - acl_name: othergroup
  - perms: rwX
  - args:
    - /usr/local/mydir
  - require:
    - group: othergroup
    - file:/usr/local/mydir

So what are we doing here?

first section [ /usr/local/mydir: ]

This just creates the dir owned by myuser:mygroup in the normal way including requiring that the user and group do exist.

second section [ usr_local_mydir_defaultacl: ]

This creates the ‘default’ ACL [so that the settings will apply to any new files or dirs created under it] by using module.run to run acl.modfacl and assigning the arguments needed:

arguments

‘acl_type’ sets the type of acl [wow! Crazy right?]. In this case we want a default acl for a group [the -d g: part of the command line]’
acl_type: 'default:group'

‘acl_name’ is a bit misleading. It’s actually the name of the user or group you want to set the ACL for, in this case ‘othergroup’
acl_name: othergroup

‘perms’ as you would guess is the actual perms you want to set. The upper-case ‘X’ here means that only dirs will be executable, not files.
perms: rwX

‘args’ is arguments to the module. In this case we are only giving it the name of the directory we want to set the ACL on.

args:
  - /usr/local/mydir

And finally ‘require’ just makes it so we require that the dir actually exists.

require:
  - file: /usr/local/mydir

third section [ usr_local_mydir_activeacl: ]

This is exactly the same as the second section [ usr_local_mydir_defaultacl: ] except that for ‘acl_type’ we just use:
acl_type: group
as we are just setting the active acl, not a ‘default’ acl.

Conclusion

Obviously this is a simplified state. In more complicated environments where you have a lot of dirs/files to create and set ACLs for, you’ll probably want to use jinja to loop through pillar data that specify the dirs, owner, group, perms, ACLs, etc. But this at least gives you an idea of how to actually get a state to set ACLs beyond the overly simple abilities of salt.states.linux_acl.