# When you throw in the towel on declarative

- Link: https://www.agilicus.com/when-you-throw-in-the-towel-on-declarative/
- Published: 2019-03-28T19:52:27+00:00
- Author: Don Bowman

I’ve [talked](https://www.agilicus.com/i-declare-make-it-so/) a lot recently about
the declarative versus imperative viewpoints. Its the [Lilliput vs Blefuscu](https://en.wikipedia.org/wiki/Lilliput_and_Blefuscu)
of our time. Its the vi versus emacs saga.

Today I ran into a scenario that I just threw in the towel on. I had a largish yaml
file (~300 lines) that is actually a config to a container (e.g. its not Kubernetes
yaml).

I’m using [kustomize](https://github.com/kubernetes-sigs/kustomize) which means 
i cannot use the tricks I would in [helm](https://github.com/helm/helm) with ‘tpl’
and {{ }} (those are imperative or templating!).

I need to change one line in it per environment (a hostname). And I really didn’t
feel good about copying the file into multiple output directories.

After an hour, I threw in the towel. The declarative police will come and get me,
but I present to you my solution. Open sourced for your pleasure.

See my new container ‘[envsubst](https://github.com/Agilicus/envsubst)‘. It auto-
builds into [dockerhub](https://hub.docker.com/r/agilicus/envsubst) for you lazy
folks. You are one

    ```wp-block-preformatted
    docker pull agilicus/envsubst
    ```

away from this big pile of perfection.

It’s simple. This container takes arguments in the form input:output. _input_ will
be passed through envsubst and redirected to _output_, making directories as needed.

    ```wp-block-preformatted
    docker run --rm -it agilicus/envsubst /etc/passwd:/dev/stdout
    ```

So e.g.:

    ```wp-block-preformatted
    docker run --rm -it agilicus/envsubst /config/ifile:/etc/config/dir/ofile
    ```

will take _ifile_, run through _envsubst_, `mkdir -p /etc/config/dir`, and place
the output in `/etc/config/dir/ofile`

Now, from Kubernetes, I make an `emptyDir: {}`. I mount it (read-only) in my ultimate
container, and read-write in this new one (as an initContainer). I pass _args_ as
the list of files above. Presto. All environment variables are expanded. Into that
big grotty yaml file that started this problem i place a `${THE_URL}`. And I’m done.

Am I proud of this? Well, I don’t have a lot of skin in the declarative vs imperative
game. So. Um. I’m done with it.
