Implementing

Managing a centralized OpenLDAP server for a modern DevOps stack (integrating tools like GitLab, Jenkins, Nexus, and HashiCorp Vault) requires a robust directory structure. Often, this means adopting a Role-Based Access Control (RBAC) model using groupOfNames for application access, alongside posixAccount attributes for Linux SSH authentication.

While many lightweight LDAP web interfaces exist, they often rigidly expect a pure Unix/Linux schema (forcing the use of posixGroup and memberUid), which breaks compatibility with modern applications. In this article, I will show you how to implement LDAP Account Manager (LAM) on Kubernetes. LAM natively understands complex directory trees and seamlessly handles groupOfNames structures.

https://github.com/LDAPAccountManager


1. The Challenge with Persistent Volumes in LAM Docker Images

When deploying the official LAM Docker image (ghcr.io/ldapaccountmanager/lam) in Kubernetes, you need a Persistent Volume (PV) to store the configuration profiles. However, mounting an empty PersistentVolumeClaim directly into the /var/lib/ldap-account-manager/config path hides the default configuration files shipped inside the container, causing it to crash immediately with a No such file or directory error.

To solve this, we use an initContainer. The initialization step temporarily mounts the volume, copies the default factory configurations into it, and then allows the main container to start safely.


2. The Kubernetes Manifest

Create the deployment manifest file. I will use vi for this:

Bash

vi lam-k8s.yaml

Paste the following configuration. This includes the PVC, the Deployment with the initContainer fix, the Service, and an Nginx Ingress to expose the UI.

YAML

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: lam-config-pvc
  namespace: ldap
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: lam-gui
  namespace: ldap
spec:
  replicas: 1
  selector:
    matchLabels:
      app: lam-gui
  template:
    metadata:
      labels:
        app: lam-gui
    spec:
      initContainers:
      - name: init-lam-config
        image: ghcr.io/ldapaccountmanager/lam:9.5.rc1
        command: ["/bin/sh", "-c"]
        args:
          - |
            if [ ! -f /mnt/config/unix.sample.conf ]; then
              echo "Copying default LAM configs to persistent volume..."
              cp -a /var/lib/ldap-account-manager/config/* /mnt/config/
            fi
        volumeMounts:
        - name: lam-config
          mountPath: /mnt/config
      containers:
      - name: lam
        image: ghcr.io/ldapaccountmanager/lam:9.5.rc1
        ports:
        - containerPort: 80
        volumeMounts:
        - name: lam-config
          mountPath: /var/lib/ldap-account-manager/config
      volumes:
      - name: lam-config
        persistentVolumeClaim:
          claimName: lam-config-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: lam-svc
  namespace: ldap
spec:
  selector:
    app: lam-gui
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: lam-ingress
  namespace: ldap
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "8m"
spec:
  ingressClassName: nginx
  rules:
  - host: ldapman.devops-db.internal
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: lam-svc
            port:
              number: 80

Apply the deployment to your cluster:

Bash

kubectl apply -f lam-k8s.yaml

3. Configuring the LAM Server Profile

Once the pod is Running, navigate to your Ingress URL (e.g., http://ldapman.devops-db.internal). Click on the “LAM configuration” link in the upper right corner.

The default master password is lam.

Server Settings

In the General Settings tab, configure the connection to your OpenLDAP backend.

  • Server address: Specify your OpenLDAP URI (e.g., ldap://ldap.devops-db.info:389).
  • Tree suffix: Define the base DN of your directory (e.g., dc=ldap,dc=devops-db,dc=info).
  • List of valid users: Input the administrative Bind DN you use to manage LDAP (e.g., cn=admin,dc=ldap,dc=devops-db,dc=info).
  • Don’t forget to change your Profile Password.

Account Types & List Attributes Fix

Navigate to the Account types tab. By default, LAM might throw a List attributes are invalid! error if the fresh configuration is blank. This field determines which columns are displayed in the UI tables.

Update the List attributes with the following syntax to fix the error and format the columns properly:

Users: 
    LDAP suffix: dc=ldap,dc=devops-db,dc=info
    List Attributes: dc=ldap,dc=devops-db,dc=info
Groups:
    LDAP suffix: dc=ldap,dc=devops-db,dc=info
    List Attributes: #cn;#gidNumber;#memberUID;#description

Ensure your LDAP suffix for Users points to your specific organizational unit (e.g., ou=UserGroups,dc=ldap...) and the Groups suffix points to your RBAC container (e.g., ou=SecurityGroups,dc=ldap...).


4. Validating the Directory Tree

Save the configuration and log in to the main interface using your administrative Bind DN password. If configured correctly, LAM will display your entire directory structure exactly as it was designed, preserving the separation between Service Groups, Security Groups, and User Groups.

You can now natively manage groupOfNames memberships for applications and posixAccount mappings for Linux hosts directly from the web interface without causing schema violations.