<p>I try to set the value of the ssl-session-cache in my configmap for ingress-controller,</p>

<p>the problem is, that i can't find how to write it correct.</p>

<p>I need following changes in the nginx config:  </p>

<p><code>ssl-session-cache builtin:3000 shared:SSL:100m</code></p>

<p><code>ssl-session-timeout: 3000</code></p>

<p>when i add 
<code>ssl-session-timeout: "3000"</code> to the config map, it works correct - this i can see in nginx-config few seconds later. </p>

<p>but how i should write ssl-session-cache? </p>

<p><code>ssl-session-cache: builtin:"3000" shared:SSL:"100m"</code> goes well, but no changes in nginx</p>

<p><code>ssl-session-cache: "builtin:3000 shared:SSL:100m"</code> goes well, but no changes in nginx</p>

<p><code>ssl-session-cache "builtin:3000 shared:SSL:100m"</code> syntax error - can't change the configmap</p>

<p><code>ssl-session-cache builtin:"3000 shared:SSL:100m"</code> syntax error - can't change the configmap</p>

<p>Do someone have the idea, how to set ssl-session-cache in configmap correct?</p>

<p>Thank you!</p>

Alexander Kolin
<h2>TL;DR</h2>

<p>After digging around and test the same scenario in my lab, I've found how to make it work.</p>

<p>As you can see <a href="https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#ssl-session-cache-size" rel="nofollow noreferrer">here</a> the parameter <code>ssl-session-cache</code> requires a <strong>boolean</strong> value to specify if it will be enabled or not.</p>

<p>The changes you need is handled by the parameter <code>ssl_session_cache_size</code> and requires a string, then is correct to suppose that it would work changing the value to <code>builtin:3000 shared:SSL:100m</code> but after reproduction and dive into the nginx configuration, I've concluded that it will not work because the option <code>builtin:1000</code> is <strong><em>hardcoded</em></strong>.</p>

<p>In order to make it work as expected I've found a solution using a nginx template as a <code>configMap</code> mounted as a volume into nginx-controller pod and other <code>configMap</code> for make the changes in the parameter <code>ssl_session_cache_size</code>.</p>

<h2>Workaround</h2>

<p>Take a look in the line <strong>343</strong> from the file <code>/etc/nginx/template</code> in the nginx-ingress-controller pod:</p>

<pre><code>bash-5.0$ grep -n 'builtin:' nginx.tmpl 
343:    ssl_session_cache builtin:1000 shared:SSL:{{ $cfg.SSLSessionCacheSize }};
</code></pre>

<p>As you can see, the option <code>builtin:1000</code> is <em>hardcoded</em> and cannot be change using custom data on yout approach.</p>

<p>However, there are some ways to make it work, you could directly change the template file into the pod, but theses changes will be lost if the pod die for some reason... or you could <strong>use a custom template mounted as <code>configMap</code> into nginx-controller pod.</strong></p>

<p>In this case, let's create a <code>configMap</code> with nginx.tmpl content changing the value of the line 343 for the desired value.</p>

<ol>
<li>Get template file from nginx-ingress-controller pod, it will create a file called<code>nginx.tmpl</code> locally:</li>
</ol>

<blockquote>
  <p>NOTE: Make sure the namespace is correct.</p>
</blockquote>

<pre><code>$ NGINX_POD=$(kubectl get pods -n ingress-nginx -l=app.kubernetes.io/component=controller -ojsonpath='{.items[].metadata.name}')

$ kubectl exec $NGINX_POD -n ingress-nginx -- cat template/nginx.tmpl &gt; nginx.tmpl
</code></pre>

<ol start="3">
<li>Change the value of the line 343 from <code>builtin:1000</code> to <code>builtin:3000</code>:</li>
</ol>

<pre><code>$ sed -i '343s/builtin:1000/builtin:3000/' nginx.tmpl
</code></pre>

<p>Checking if evething is ok:</p>

<pre><code>$ grep builtin nginx.tmpl 
ssl_session_cache builtin:3000 shared:SSL:{{ $cfg.SSLSessionCacheSize }};
</code></pre>

<p>Ok, at this point we have a <code>nginx.tmpl</code> file with the desired parameter changed.</p>

<p>Let's move on and create a <code>configMap</code> with the custom nginx.tmpl file:</p>

<pre><code>$ kubectl create cm nginx.tmpl --from-file=nginx.tmpl
configmap/nginx.tmpl created
</code></pre>

<p>This will create a <code>configMap</code> called <code>nginx.tmpl</code> in the <code>ingress-nginx</code> namespace, if your ingress' namespace is different, make the proper changes  before apply.</p>

<p>After that, we need to edit the nginx-ingress deployment and add a new <code>volume</code> and a <code>volumeMount</code> to the containers spec. In my case, the nginx-ingress deployment name <code>ingress-nginx-controller</code> in the <code>ingress-nginx</code> namespace. </p>

<p>Edit the deployment file:</p>

<pre><code>$ kubectl edit deployment -n ingress-nginx ingress-nginx-controller
</code></pre>

<p>And  add the following configuration in the correct places:</p>

<pre><code>...
        volumeMounts:
        - mountPath: /etc/nginx/template
          name: nginx-template-volume
          readOnly: true
...
      volumes:
      - name: nginx-template-volume
        configMap:
          name: nginx.tmpl
          items:
          - key: nginx.tmpl
            path: nginx.tmpl
...
</code></pre>

<p>After save the file, the nginx controller pod will be recreated with the <code>configMap</code> mounted as a file into the pod.</p>

<p>Let's check if the changes was propagated:</p>

<pre><code>$ kubectl exec -n ingress-nginx $NGINX_POD -- cat nginx.conf | grep -n ssl_session_cache
223:    ssl_session_cache builtin:3000 shared:SSL:10m;
</code></pre>

<p>Great, the first part is done!</p>

<p>Now for the <code>shared:SSL:10m</code> we can use the same approach you already was used: <code>configMap</code> with the specific parameters as mentioned in this <a href="https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#ssl-session-cache-size" rel="nofollow noreferrer">doc</a>.</p>

<p>If you remember in the nginx.tmpl, for <code>shared:SSL</code> there is a variable called <strong>SSLSessionCache</strong> (<code>{{ $cfg.SSLSessionCacheSize }}</code>), in the <a href="https://github.com/kubernetes/ingress-nginx/blob/master/internal/ingress/controller/config/config.go" rel="nofollow noreferrer">source code</a> is possible to check that the variable is represented by the option <code>ssl-session-cache-size</code>:</p>

<pre class="lang-golang prettyprint-override"><code>340  // Size of the SSL shared cache between all worker processes.
341  // http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_cache
342  SSLSessionCacheSize string `json:"ssl-session-cache-size,omitempty"`
</code></pre>

<p>So, all we need to do is create a <code>configMap</code> with this parameter and the desired value:</p>

<pre><code>kind: ConfigMap
apiVersion: v1
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
data:
  ssl-session-cache-size: "100m"
</code></pre>

<blockquote>
  <p>Note: Adjust the namespace and configMap name for the equivalent of your environment.</p>
</blockquote>

<p>Applying this <code>configMap</code> NGINX will reload the configuration and make the changes in the configuration file.</p>

<p>Checking the results:</p>

<pre><code>$ NGINX_POD=$(kubectl get pods -n ingress-nginx -l=app.kubernetes.io/component=controller -ojsonpath='{.items[].metadata.name}')

$ kubectl exec -n ingress-nginx $NGINX_POD -- cat nginx.conf | grep -n ssl_session_cache
223:    ssl_session_cache builtin:3000 shared:SSL:100m;
</code></pre>

<h2>Conclusion</h2>

<p>It would work as expected,  unfortunately, I can't find a way to add a variable in the <code>builtin:</code>, so we will continue using it <em>hardcoded</em> but at this time it will be a configMap that you can easily make changes if needed.</p>

<h2>References:</h2>

<p><a href="https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/custom-template.md" rel="nofollow noreferrer">NGINX INgress Custom template</a></p>

<p><a href="https://github.com/kubernetes/ingress-nginx/blob/master/internal/ingress/controller/config/config.go" rel="nofollow noreferrer">NGINX Ingress Source Code</a></p>
