<p>I would like to generate dynamic configuration files (redis, database) based on values (<code>ex.redis_host</code>) collected from env variables which will differ from service to service and put it on a specific location (<code>config/redis.yml</code>).</p>

<p>How will i be able to achieve it? </p>

<p>Dynamic Config file generation can include creation of</p>

<ol>
<li><p><strong>Config file structure</strong>:</p>

<p>The config files for e.g redis.yaml might varry for development, staging, production environments.
eg: </p>

<p>staging</p>

<pre><code>${ENVIRONMENT}:
    host: ${REDIS_HOST}
    namespace: ${REDIS_NAMESPACE}
    port: 6379
</code></pre>

<p>production:</p>

<pre><code>${ENVIRONMENT}:
    host: ${REDIS_HOST}
    namespace: ${REDIS_NAMESPACE}
    port: 6379
    connect_timeout: ${REDIS_CONNECT_TIMEOUT}
    timeout: {REDIS_TIMEOUT}
</code></pre></li>
<li><p><strong>Config file content</strong>:</p>

<p>The content of the config files could again be populated dynamically.</p></li>
</ol>

<p>we could generate <code>config-templates</code> or <code>config-file-structure</code> using helm and mount them in the required place (say config/redis.yaml ) inside the pod.Then these config-templates can be converted/rendered into proper file using utilities at container run time.</p>

<p>Dynamic creation of config files based on the environment/environment_variables could be achieved using following ways.</p>

<p><strong>The Bash Way</strong> (using <code>eval</code> and <code>cat</code>):</p>

<ol>
<li><p>Create a file named <code>inator</code> with the following content</p>

<pre><code>#!/bin/bash
eval "cat &lt;&lt;EOF 
$(&lt;$1)
EOF
" | tee $1 &gt;/dev/null
</code></pre></li>
<li><p>Make inator as executable and place it inside the docker image and execute it as a ENTRYPOINT script</p></li>
<li><p>Considering the env varibles are avilable inside the pod/container </p>

<p>eg:
staging</p>

<pre><code>$ env
ENVIRONMENT=staging
REDIS_HOST=abc.com
REDIS_NAMESPACE=inator

$ cat config/redis.yaml
${ENVIRONMENT}:
   host: ${REDIS_HOST}
   namespace: ${REDIS_NAMESPACE}
   port: 6379

$ ./inator config/redis.yaml
$ cat config/redis.yaml
staging:
  host: abc.com
  namespace: inator
  port: 6379
</code></pre>

<p>production</p>

<pre><code>$ env
ENVIRONMENT=production
REDIS_HOST=redis.prod.com
REDIS_NAMESPACE=prod
REDIS_CONNECT_TIMEOUT=5
TIMEOUT=10

$ cat config/redis.yaml
${ENVIRONMENT}:
   host: ${REDIS_HOST}
   namespace: ${REDIS_NAMESPACE}
   port: 6379
   connect_timeout: ${REDIS_CONNECT_TIMEOUT}           
   timeout: {REDIS_TIMEOUT}

$ ./inator config/redis.yaml
$ cat config/redis.yaml
production:
  host: redis.prod.com
  namespace: prod
  port: 6379
  connect_timeout: 5
  timeout: 10
</code></pre></li>
</ol>

<p>Advantages:
no additional package required.</p>

<p><strong>The dockerize way</strong>:</p>

<p><a href="https://github.com/jwilder/dockerize" rel="nofollow noreferrer">dockerize</a> is a utility to simplify running applications in docker containers. It internally uses go templates to populate config files from environment variabels. </p>

<p>Have a look at this blog post <a href="http://steveadams.io/2016/08/18/Environment-Variable-Templates.html" rel="nofollow noreferrer">Environment Variable Templates</a> for further information.</p>
