diff --git a/ldap/.helmignore b/ldap/.helmignore
new file mode 100644
index 0000000000..f0c1319444
--- /dev/null
+++ b/ldap/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/ldap/Chart.yaml b/ldap/Chart.yaml
new file mode 100644
index 0000000000..e4d426ae45
--- /dev/null
+++ b/ldap/Chart.yaml
@@ -0,0 +1,19 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+apiVersion: v1
+description: A Helm chart for LDAP
+name: ldap
+version: 0.1.0
+home: https://www.openldap.org/
+maintainers:
+  - name: OpenStack-Helm Authors
diff --git a/ldap/requirements.yaml b/ldap/requirements.yaml
new file mode 100644
index 0000000000..5669e12cfd
--- /dev/null
+++ b/ldap/requirements.yaml
@@ -0,0 +1,16 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+dependencies:
+  - name: helm-toolkit
+    repository: http://localhost:8879/charts
+    version: 0.1.0
diff --git a/ldap/templates/_helpers.tpl b/ldap/templates/_helpers.tpl
new file mode 100644
index 0000000000..f0d83d2edb
--- /dev/null
+++ b/ldap/templates/_helpers.tpl
@@ -0,0 +1,16 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+*/}}
+{{- define "fullname" -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/ldap/templates/service.yaml b/ldap/templates/service.yaml
new file mode 100644
index 0000000000..bb789e88e3
--- /dev/null
+++ b/ldap/templates/service.yaml
@@ -0,0 +1,30 @@
+{{/*
+Copyright 2017 The Openstack-Helm Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/}}
+
+{{- if .Values.manifests.service }}
+{{- $envAll := . }}
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ tuple "ldap" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}
+spec:
+  ports:
+    - name: db
+      port: {{ tuple "ldap" "internal" "ldap" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
+  selector:
+{{ tuple $envAll "ldap" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }}
+{{- end }}
diff --git a/ldap/templates/statefulset.yaml b/ldap/templates/statefulset.yaml
new file mode 100644
index 0000000000..0d0fac98de
--- /dev/null
+++ b/ldap/templates/statefulset.yaml
@@ -0,0 +1,80 @@
+{{/*
+Copyright 2017 The Openstack-Helm Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/}}
+
+{{- if .Values.manifests.statefulset }}
+{{- $envAll := . }}
+---
+apiVersion: apps/v1beta1
+kind: StatefulSet
+metadata:
+  name: ldap
+spec:
+  serviceName: {{ tuple "ldap" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}
+  replicas: {{ .Values.pod.replicas.server }}
+  template:
+    metadata:
+      labels:
+{{ tuple $envAll "ldap" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }}
+    spec:
+      affinity:
+{{ tuple $envAll "ldap" "server" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }}
+      nodeSelector:
+        {{ .Values.labels.node_selector_key }}: {{ .Values.labels.node_selector_value }}
+      containers:
+      - name: ldap
+        image: {{ .Values.images.ldap }}
+        imagePullPolicy: {{ .Values.images.pull_policy }}
+        env:
+        - name: LDAP_DOMAIN
+          value: {{ .Values.openldap.domain }}
+        - name: LDAP_ADMIN_PASSWORD
+          value: {{ .Values.openldap.password }}
+        ports:
+        - containerPort: {{ tuple "ldap" "internal" "ldap" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
+{{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
+        volumeMounts:
+        - name: ldap-data
+          mountPath: /var/lib/ldap
+        - name: ldap-config
+          mountPath: /etc/ldap/slapd.d
+{{- if not .Values.storage.pvc.enabled }}
+      volumes:
+      - name: ldap-data
+        hostPath:
+          path: {{ .Values.storage.host.data_path }}
+      - name: ldap-config
+        hostPath:
+          path: {{ .Values.storage.host.config_path }}
+{{- else }}
+  volumeClaimTemplates:
+  - metadata:
+      name: ldap-data
+    spec:
+      accessModes: [ "ReadWriteOnce" ]
+      storageClassName: {{ .Values.storage.pvc.class_name }}
+      resources:
+        requests:
+          storage: {{ .Values.storage.pvc.size }}
+  - metadata:
+      name: ldap-config
+    spec:
+      accessModes: [ "ReadWriteOnce" ]
+      storageClassName: {{ .Values.storage.pvc.class_name }}
+      resources:
+        requests:
+          storage: {{ .Values.storage.pvc.size }}
+{{- end }}
+{{- end }}
diff --git a/ldap/values.yaml b/ldap/values.yaml
new file mode 100644
index 0000000000..1ee4faf4c7
--- /dev/null
+++ b/ldap/values.yaml
@@ -0,0 +1,73 @@
+# Copyright 2017 The Openstack-Helm Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Default values for ldap.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+pod:
+  affinity:
+    anti:
+      type:
+        default: preferredDuringSchedulingIgnoredDuringExecution
+      topologyKey:
+        default: kubernetes.io/hostname
+  replicas:
+    server: 1
+  resources:
+    enabled: false
+    server:
+      requests:
+        memory: "128Mi"
+        cpu: "100m"
+      limits:
+        memory: "1024Mi"
+        cpu: "2000m"
+images:
+  ldap: "docker.io/osixia/openldap:1.1.9"
+  pull_policy: IfNotPresent
+
+storage:
+  pvc:
+    enabled: true
+    size: 2Gi
+    class_name: general
+  host:
+    data_path: /data/openstack-helm/ldap
+    config_path: /data/openstack-helm/config
+
+labels:
+  node_selector_key: openstack-control-plane
+  node_selector_value: enabled
+
+endpoints:
+  cluster_domain_suffix: cluster.local
+  ldap:
+    hosts:
+      default: ldap
+    host_fqdn_override:
+      default: null
+    path: null
+    scheme: 'http'
+    port:
+      ldap:
+        default: 389
+
+openldap:
+  domain: cluster.local
+  password: password
+
+manifests:
+  statefulset: true
+  service: true
diff --git a/tools/gate/launch-osh/basic.sh b/tools/gate/launch-osh/basic.sh
index 82d1606424..0e3e353a29 100755
--- a/tools/gate/launch-osh/basic.sh
+++ b/tools/gate/launch-osh/basic.sh
@@ -93,6 +93,10 @@ else
   helm install --namespace=openstack ${WORK_DIR}/mariadb --name=mariadb \
     --set pod.replicas.server=1
 fi
+
+helm install --namespace=openstack ${WORK_DIR}/ldap --name=ldap
+kube_wait_for_pods openstack ${POD_START_TIMEOUT_OPENSTACK}
+
 helm install --namespace=openstack ${WORK_DIR}/memcached --name=memcached
 kube_wait_for_pods openstack ${POD_START_TIMEOUT_OPENSTACK}