How to inject environment variables in Varnish configuration

I've managed to parse my vcl

backend front1 {
    .host = ${FRONT1_PORT_8080_TCP_ADDR};
}

With a script:

envs=`printenv`

for env in $envs
do
    IFS== read name value <<< "$env"

    sed -i "s|\${${name}}|${value}|g" /etc/varnish/default.vcl
done

Now you can use the VMOD Varnish Standard Module (std) to get environment variables in the VCL, for example:

set req.backend_hint = app.backend(std.getenv("VARNISH_BACKEND_HOSTNAME"));

See documentation: https://varnish-cache.org/docs/trunk/reference/vmod_std.html#std-getenv


Note: it doesn't work for backend configuration, but could work elsewhere. Apparently backends are expecting constant strings and if you try, you'll get Expected CSTR got 'std.fileread'.

You can use the fileread function of the std module, and create a file for each of your environment variables.

before running varnishd, you can run:

mkdir -p /env; \
env | while read envline; do \
    k=${envline%%=*}; \
    v=${envline#*=}; \
    echo -n "$v" >"/env/$k"; \
done

And then, within your varnish configuration:

import std;

...

backend front1 {
    .host = std.fileread("/env/FRONT1_PORT_8080_TCP_ADDR");
    .port = std.fileread("/env/FRONT1_PORT_8080_TCP_PORT");
}

I haven't tested it yet. Also, I don't know if giving a string to the port configuration of the backend would work. In that case, converting to an integer should work:

.port = std.integer(std.fileread("/env/FRONT1_PORT_8080_TCP_PORT"), 0);