* saltstack Jinja templating [1]
* GitLab CI `include` directive for including and merging external CI files together [2]
A few tools that I have seen take a decently pragmatic approach:
* Kubernetes resources that use ConfigMap and `envFrom` that declaratively say where to resolve a value from [3]
* Circle CI commands which offer some reusability with its "commands" and "executors" type features [4]. To me, Circle CI has both good and bad aspects with some templating and some clever patterns
On the other side of things, there is essentially fully programmable type configurations like Jenkins Pipeline Groovy `Jenkinsfile`, which can be a nightmare, too.
I think it is tough to find a sweet spot between making it configurable and expressive for users while retaining a low barrier of entry and not turning the configuration into a complete program itself. Tools like Terraform are trying to find that sweet spot as they slowly introduce more programmatic ways of configuration while still being declarative, like the fairly recent introduction of if statements and soon (I think) to be released for loops. As soon as users of a tool and service have more complex use cases, there needs to be some way to solve that. The most common way (it seems) is taking the easy and familiar of introducing templating.
[1]: https://docs.saltstack.com/en/latest/topics/jinja/index.html
[2]: https://docs.gitlab.com/ee/ci/yaml/#include
[3]: https://kubernetes.io/docs/reference/generated/kubernetes-ap...
[4]: https://circleci.com/docs/2.0/configuration-reference/#comma...