After installation, the first thing is to do is tell your puppet environment what LDAP servers you have in your organization. Although most organizations prefer to keep user information as centrally managed as possible, reality is that most organizations have multiple LDAP servers they need to manage.

Add the ldap_server to the manifest

Using the ldap_server type you can add information about your servers to the Puppet manifest. Here is an example:

ldap_server { 'production_ldap':
  address           => 'prod_ldap.example.com',
  port              => '389',
  user_dn           => 'cn=admin,dc=example,dc=org',
  password          => 'admin',
  verify_ssl        => 'false',
  use_ssl           => 'false',
  base              => 'dc=example,dc=org',
}

The ldap_server type contains everyting needed to connect to the LDAP server and perform operations.

Because Puppet needs this information later, it will store it in /etc/ldap_server.yaml. To ensure safety, the file is adequately secured, and the password is encrypted.

When you have more LDAP servers, you need to add them to your manifest too.

Ensuring an container entry

When you want manage entries in “your own” container, you must first ensure that the container exists. For example:

ldap_principal { 'production_ldap:ou=mydepartment,dc=example,dc=org':
  ensure     => 'present',
  purge      => true,
  attributes => {
                'objectclass'  => ['organizationalUnit', 'top'],
                'ou'           => 'mydepartment',
              },
}

This example ensures there is an organizationalUnit LDAP container mydepartment. The purge property set to true makes sure that entries in this container that are not in the manifest, will be removed by puppet. This ensures there are no unmanaged LDAP entries in our container.

Enter persons

Now that we have the container, we can enter all the persons (or another type of entries) to it.

ldap_principal { 'production_ldap:cn=kermit,ou=muppetshow,dc=example,dc=org':
  ensure     => 'present',
  purge_attributes => true,
  attributes => {
    'objectclass'  => ['top', 'inetOrgPerson'],
    'userPassword' => "{SSHA512}2ZsyGTxVyEw14Cu9D/OXpTddfy/387D/rlR6R0VVdRIz+3Wn52fSYZpKAP1S\n9J/kRbkoBiPK/9eZMOZV6cgidzEyMzQ1Njc4",
    'givenName'    => 'Kermit the frog',
    'cn'           => 'kermit,
    'sn'           => 'Kermit',
  },
}

Here we make sure there is a kermit entry in the muppetshow. If the LDAP server doesn’t contain an entry, Puppet will create it. If the LDAP server already contains this entry, but some of the properties are different, Puppet will update the specified attributes. Because the purge_attributes parameter is set to true any other attributes available on the LDAP server, but not in the manifest, will be removed.

Manage group entries

The LDAP directory also can contain groups. You can manage a group with the present_in or absent_in properties. Here we create a group muppets and we make sure kermit is in that group.

ldap_principal { 'production_ldap:cn=muppets,ou=muppetshow,dc=example,dc=org':
  ensure     => 'present',
  attributes => {
    'objectclass'  => ['top', 'groupOfNames'],
  },
  present_in => {
    'member'       => [
      'cn=kermit,ou=muppetshow,dc=example,dc=org',
    ],
  },
}

All other entries in the group muppets are left as the are. We only make sure that kermit is in the group. When we want to make sure an entry is NOT available in the group, we use the [absent_in(/docs/ldap_principal/ldap_principal.html#ldap_principal_absent_in)] property:

...
   absent_in       => {
     'member'       => [
       'cn=piggy,ou=muppetshow,dc=example,dc=org',
     ],
   },
...

Making sure an entry is not available

Like standard in Puppet, removing an entry is easy:

ldap_principal { 'production_ldap:cn=gonzo,ou=muppetshow,dc=example,dc=org':
  ensure => 'absent',
}

Managing the password

In the examples before, we use the hashed password. Some of the LDAP servers don’t allow this, and you must use an unencrypted password. But because Puppet needs to manage encrypted attributes in an idempotent way, we need some way of control over the encrypted value. You can do this by using the transform property.

Here is an example:

ldap_principal { 'docker:cn=piggy,ou=muppetshow, dc=example,dc=org':
  ensure     => 'present',
  attributes => {
    'cn'           => 'piggy',
    'givenname'    => 'Miss Piggy',
    'objectclass'  => ['top', 'inetOrgPerson'],
    'sn'           => 'piggy',
    'userpassword' => 'MissPiggy'
  },
  transform  => {'userpassword' => 'hashed'},
}

In this definition, the value specified at the attribute ‘userPassword’, will first be presented to the Puppet function hashed_compare and then compared with the value returned from the ldap server. The specified function will NOT be applied before sending the value to the LDAP server.

At this point in time, we support passwords using the SSHA512 hash.

Manifest ordering

As you can see in the examples, we add no explicit ordering. This is because the ldap_principal type supports setting up automatic relations on all entries. When ensuring entries it will make sure the parents are created before the children. When absenting entries, it will first remove the children before removing the parents.

Basic setup done

This concludes setting up the basic entries. This example should help you get started and fill your manifest