In a S-expression-based configuration language, one would either embed an S-expression-based programming language, or generate the S-expressions with a programming language which can manipulate S-expressions.
I don't think that it's that easy to get away from needing Turing-completeness in general. No reason you can't still support rollbacks, dependencies and diffs anyway.
Also there's this school of thought that attributes most security problems to people accidentally using Turing-complete languages where they meant to use something less powerful. Consider vulnerability to arbitrary code execution through user input injection, which could be interpreted by your program being a "parser" (so-called "shotgun parser" - it's implicitly distributed throughout your code base) for a Turing-complete superset of what was supposed to be a list of accepted inputs. There are pretty good talks about this line of thought and I personally find it pretty interesting.
But none of this affects the fact that in complicated enough programs, you need "configuration" to be more code than data, which leads people not knowing of Lisp to reinvent a subset of it in XML or JSON or something similar.
Why not? Configurations are collections of items, and among the things Lisp excels at is…lists of atoms.
Take a look at https://github.com/ansible/ansible-examples/tree/master/lamp... (a simple LAMP stack implemented in Ansible).
It uses a .ini-style file to manage lists of hosts, e.g.:
Why not put that in a list? The Ansible playbooks are YAML lists. There's no particular reason that: is more readable than: or: In fact, I'd argue that both Lispy representations are much more readable.