Then again, we have Chef (ruby DSL), and from experience I've found that they tend to turn into a mess that very easily can become hard to reason about. Although, I'm not sure if this is because of the design of Chef itself, or just simply because it uses a real language.
See ansible and the YAML config files.
In this case, a real language would have been a better choice.
Also, sometimes you need to generate config files. In that case, templating is not always a good choice.