How to Retrieve a User’s Home Directory Path in Puppet When managehome=false


2 views

When creating users in Puppet with managehome => false, we're explicitly telling Puppet not to create or manage the home directory. This creates a common scenario where we need to reference the user's home directory path without Puppet having created it.

Here are three robust approaches to determine the home directory path:

# Method 1: Using the 'home' parameter in user resource
user { $username:
    comment => "$name",
    shell   => "$shell",
    managehome => false,
    home    => "/home/${username}",  # Explicitly set home directory
    password => "$password",
    groups => $groups
}

# Later reference:
$key = "/home/${username}/file"

For more dynamic solutions when you don't know the path structure:

# Method 2: Using the user resource's automatic home parameter
user { $username:
    ensure     => present,
    managehome => false,
    system     => false  # Ensures standard home directory location
}

# Puppet will automatically set home to /home/${username} for non-system users
$key = User[$username]['home'] + "/file"

For systems where home directories might be in different locations:

# Method 3: Using custom facts or Hiera data
case $facts['os']['family'] {
    'Windows': { $homedir = "C:/Users/${username}" }
    'Darwin':  { $homedir = "/Users/${username}" }
    default:   { $homedir = "/home/${username}" }
}

user { $username:
    managehome => false,
    home       => $homedir
}

$key = "${homedir}/file"
  • Always explicitly set the home parameter when managehome is false
  • Consider using Hiera to manage home directory paths across different environments
  • For system users, be explicit about home directory locations as they vary more between distributions

If you encounter errors about missing home directories:

# Ensure the directory exists before placing files
exec { "create_${username}_homedir":
    command => "mkdir -p ${homedir} && chown ${username}:${username} ${homedir}",
    unless  => "test -d ${homedir}",
    path    => ['/bin', '/usr/bin'],
    before  => File[$key]
}

When creating users in Puppet with managehome => false, the system won't automatically create or manage the home directory. This becomes problematic when you later need to deploy files to that user's home directory, as Puppet doesn't inherently know the path.

Here are several approaches to determine a user's home directory path:

1. Using the user resource's home attribute

The most straightforward method is to explicitly set the home directory when creating the user:

user { $username:
    comment => "$name",
    shell   => "$shell",
    managehome => false,
    home    => "/home/${username}", # Explicitly set home directory
    password => "$password",
    groups => $groups
}

2. Using the getent command

For systems where you can't predict the home directory location, use the getent command:

$homedir = generate('/bin/sh', '-c', "getent passwd ${username} | cut -d: -f6")

3. Using Puppet's built-in facts

On most Linux systems, you can construct the path using the $::id fact:

$homedir = "/home/${username}"

Here's how to implement this in a complete manifest:

# Define user without managing home
user { $username:
    ensure     => present,
    managehome => false,
    home       => "/home/${username}", # Set home directory explicitly
    shell      => '/bin/bash',
    groups     => ['sudo'],
}

# Deploy file to home directory
file { "/home/${username}/.ssh/authorized_keys":
    ensure  => file,
    owner   => $username,
    group   => $username,
    mode    => '0600',
    content => $ssh_key,
    require => User[$username],
}

For more complex environments:

  • For LDAP/NIS users: Use getent as shown above
  • For Windows systems: Use $env:USERPROFILE in your exec resources
  • For custom home locations: Store the path in Hiera or your ENC

When working with home directories in Puppet:

  1. Always explicitly set the home attribute when creating users
  2. Use the require or subscribe metaparameters to ensure proper ordering
  3. Consider using the puppetlabs/stdlib module's getvar() function for complex cases
  4. Test your manifests on different operating systems