Puppet: Get users home directory

Hm, i think there you'll need a facter modul to do that and a little hacky manifest file...

facter module: This will register facter variables for all users. like "home_root" or "home_apache".

require 'etc'

Etc.passwd { |user|

   Facter.add("home_#{user.name}") do
      setcode do
         user.dir
      end
   end

}

and then you can use them inside your manifest file like this:

$username = "root"
$home = "home_$username"
$home_path = inline_template("<%= scope.lookupvar('::$home') %>")

file { "$home_path/test.txt":
   content => "huhu",
}

Perhaps there is a better way, but i'm afraid not.


I tried to find a solution for the exactly same problem, and it turned out it's best to take a slightly different approach.

Define home directory explicitly, for example:

user { $username:
    comment    => "comment",
    home       => "/home/${username}",
    managehome => false,
    # ...
}

When managehome is false, the home directory is not even created. So you have to specifically define it. It's often best to make a custom definition for the whole user:

define custom_user($username, $password) {
    user { $username:
        home     => "/home/${username}",
        password => $password,
        # etc.
    }
    file { "/home/${username}":
        ensure  => directory,
        owner   => $username,
        require => User[$username],
        # etc.
    }
}

You can add more parameters, for example $keyvalue, and create a keyfile if that parameter is given.

You can also define a global variable $home = "/home" (OS specific, if needed) and get home dir with "${home}/${username}".

Edit: Using hash to define user-specific home directories

More recent Puppet versions (>= 2.6) support hashes. It would be possible to define a hash containing username => /path/to/home mappings for each user:

$home = {
    normal_user => '/home/normal_user',
    backup      => '/var/backup',
    mysql       => '/var/lib/mysql'
}

For any username, it is then easy to get home directory with $home['username'].

Home directory hash with fallback

Most of the time, it would be best to have a "fallback default" if user does not exist in the hash. In theory this is possible, although syntax becomes a little cryptic and bloated:

$home = { ... }
$default_home = '/home'

user {$username:
    home => has_key($home, $username) ? {
                true => $home[$username], 
                false => "${default_home}/${username}" 
            }
    # ...
}

This question is old, but still relevant. There is in fact a better way now. Add a custom fact to [module]/lib/facter/home_dirs.rb containing the following:

require 'etc'

Facter.add(:home_dirs) do
  setcode do

    home_dirs = {}   
    Etc.passwd { |user|
      home_dirs[user.name] = user.dir
    }

    home_dirs

  end
end

Then you can access the data in the manifest thusly:

$facts['home_dirs']['some_username']

Bear in mind that this only works if the user already exists prior to the puppet run. If the user is getting created during the run, the home directory should be already known or at least predictable. Puppet is designed to create order, after all.

Hope this helps someone.