<p>I have a Kubernetes cluster with Elasticsearch currently deployed.</p>
<p>The Elasticsearch coordinator node is accessible behind a service via a <code>ClusterIP</code> over HTTPS. It uses a self-signed TLS certificate.</p>
<p>I can retrieve the value of the CA:</p>
<pre class="lang-sh prettyprint-override"><code>kubectl get secret \
    -n elasticsearch elasticsearch-coordinating-only-crt \
    -o jsonpath=&quot;{.data.ca\.crt}&quot; | base64 -d
-----BEGIN CERTIFICATE-----
MIIDIjCCAgqgAwIBAgIRANkAx51S
...
...
</code></pre>
<p>I need to provide this as a <code>ca.crt</code> to other app deployments.</p>
<blockquote>
<p>Note: The Elasticsearch deployment is an an <code>elasticsearch</code> Kubernetes namespace. New deployments will be in different namespaces.</p>
</blockquote>
<p>An example of this is a deployment of kafka that includes a <a href="https://docs.confluent.io/kafka-connect-elasticsearch/current/configuration_options.html#security" rel="nofollow noreferrer">kafka-connect-elasticsearch/</a> sink. The sink connector uses configuration such as:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ include &quot;kafka.fullname&quot; . }}-connect
  labels: {{- include &quot;common.labels.standard&quot; . | nindent 4 }}
    app.kubernetes.io/component: connector
data:
  connect-standalone-custom.properties: |-
    bootstrap.servers={{ include &quot;kafka.fullname&quot; . }}-0.{{ include &quot;kafka.fullname&quot; . }}-headless.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }}:{{ .Values.service.port }}
    key.converter.schemas.enable=false
    value.converter.schemas.enable=false
    offset.storage.file.filename=/tmp/connect.offsets
    offset.flush.interval.ms=10000
    key.converter=org.apache.kafka.connect.json.JsonConverter
    value.converter=org.apache.kafka.connect.json.JsonConverter
    plugin.path=/usr/local/share/kafka/plugins
  elasticsearch.properties: |-
    name=elasticsearch-sink
    connector.class=io.confluent.connect.elasticsearch.ElasticsearchSinkConnector
    tasks.max=4
    topics=syslog,nginx
    key.ignore=true
    schema.ignore=true
    connection.url=https://elasticsearch-coordinating-only.elasticsearch:9200
    type.name=kafka-connect
    connection.username=elastic
    connection.password=xxxxxxxx
    elastic.security.protocol=SSL
    elastic.https.ssl.truststore.location=/etc/ssl/certs/elasticsearch-ca.crt
    elastic.https.ssl.truststore.type=PEM
</code></pre>
<p>Notice the <code>elastic.https.ssl.truststore.location=/etc/ssl/certs/elasticsearch-ca.crt</code>; that's the file I need to put inside the <code>kafka</code>-based container.</p>
<p><strong>What's the optimal way to do that with Helm templates?</strong></p>
<p>Currently I have a fork of <a href="https://github.com/bitnami/charts/tree/master/bitnami/kafka" rel="nofollow noreferrer">https://github.com/bitnami/charts/tree/master/bitnami/kafka</a>. It adds 3 new templates under <code>templates/</code>:</p>
<ul>
<li>kafka-connect-elasticsearch-configmap.yaml</li>
<li>kafka-connect-svc.yaml</li>
<li>kafka-connect.yaml</li>
</ul>
<p>The <code>configmap</code> is shown above.  The <code>kafka-connect.yaml</code> Deployment looks like this:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include &quot;kafka.fullname&quot; . }}-connect
  labels: {{- include &quot;common.labels.standard&quot; . | nindent 4 }}
    app.kubernetes.io/component: connector
spec:
  replicas: 1
  selector:
    matchLabels: {{- include &quot;common.labels.matchLabels&quot; . | nindent 6 }}
      app.kubernetes.io/component: connector
  template:
    metadata:
      labels: {{- include &quot;common.labels.standard&quot; . | nindent 8 }}
        app.kubernetes.io/component: connector
    spec:
      containers:
        - name: connect
          image: REDACTED.dkr.ecr.REDACTED.amazonaws.com/kafka-connect-elasticsearch
          imagePullPolicy: Always
          command:
            - /bin/bash
            - -ec
            - bin/connect-standalone.sh custom-config/connect-standalone-custom.properties custom-config/elasticsearch.properties
          ports:
            - name: connector
              containerPort: 8083
          volumeMounts:
            - name: configuration
              mountPath: /opt/bitnami/kafka/custom-config
      imagePullSecrets:
        - name: regcred
      volumes:
        - name: configuration
          configMap:
            name: {{ include &quot;kafka.fullname&quot; . }}-connect
</code></pre>
<p><strong>How can I modify these Kafka Helm charts to allow them to retrieve the value for <code>kubectl get secret -n elasticsearch elasticsearch-coordinating-only-crt -o jsonpath=&quot;{.data.ca\.crt}&quot; | base64 -d</code> and write its content to <code>/etc/ssl/certs/elasticsearch-ca.crt</code> ?</strong></p>

Brad Solomon
<p>Got this working and learned a few things in the process:</p>
<ul>
<li>Secret resources reside in a namespace. Secrets can only be referenced by Pods in that same namespace. (<a href="https://kubernetes.io/docs/concepts/configuration/secret/" rel="nofollow noreferrer">ref</a>). Therefore, I switched to using a shared namespace for elasticsearch + kafka</li>
<li>The secret can be used in a straightforward way as documented at <a href="https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets" rel="nofollow noreferrer">https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets</a>. This is not a Helm-specific but rather core Kubernetes feature</li>
</ul>
<p>In my case this looked like:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include &quot;kafka.fullname&quot; . }}-connect
  labels: {{- include &quot;common.labels.standard&quot; . | nindent 4 }}
    app.kubernetes.io/component: connector
spec:
  replicas: 1
  selector:
    matchLabels: {{- include &quot;common.labels.matchLabels&quot; . | nindent 6 }}
      app.kubernetes.io/component: connector
  template:
    metadata:
      labels: {{- include &quot;common.labels.standard&quot; . | nindent 8 }}
        app.kubernetes.io/component: connector
    spec:
      containers:
        - name: connect
          image: REDACTED.dkr.ecr.REDACTED.amazonaws.com/kafka-connect-elasticsearch
          imagePullPolicy: Always
          command:
            - /bin/bash
            - -ec
            - bin/connect-standalone.sh custom-config/connect-standalone-custom.properties custom-config/elasticsearch.properties
          ports:
            - name: connector
              containerPort: 8083
          volumeMounts:
            - name: configuration
              mountPath: /opt/bitnami/kafka/custom-config
            - name: ca
              mountPath: /etc/ssl/certs
              readOnly: true
      imagePullSecrets:
        - name: regcred
      volumes:
        - name: configuration
          configMap:
            name: {{ include &quot;kafka.fullname&quot; . }}-connect
        - name: ca
          secret:
            secretName: elasticsearch-coordinating-only-crt
</code></pre>
<p>This gets the <code>kafka-connect</code> pod up and running, and I can validate the certs are written there also:</p>
<pre class="lang-sh prettyprint-override"><code>$ kubectl exec -it -n elasticsearch kafka-connect-c4f4d7dbd-wbxfq \
    -- ls -1 /etc/ssl/certs

ca.crt
tls.crt
tls.key
</code></pre>
