There are some scenarios where there is no 'one tool for everything', like creating a complex OCI image, a VM image using Packer, a VM using Vagrant, configuring a network appliance or configuring an end-user workstation.
Example: super complex OCI images that attach to a CI pipeline would be better served by native packaging tools (like Jib for Java projects), but re-packaging of existing applications might depend on how green the build is. You could do a bunch of shell scripting in a Dockerfile, but once that gets big enough you'll start to need to use functions and perhaps even function libraries that you source in, but at that point you're doing a re-invention of something like Ansible and SaltStack, so depending on existing modules, knowledge, time, experience etc. you might use those instead.
Compare that to non-packaged-deliverable things like network switches and routers; those tend to be long-lived (non-ephemeral) systems, and they tend to have various inconsistent APIs between vendors, models and generations. But you may want to exchange configuration inputs and outputs with other systems so your Cloudflare rules, AWS ALBs, AWS SGs, on-prem Palo Alto firewall and on-prem Cisco switch agree on the configuration, and in such a way that it can be validated and audited constantly and consistently. Not a single named vendor does it all, especially not in a consistent and useful way. But as long as there are providers for Terraform, you can (with Terraform).
Perhaps the best way to describe how I balance it (or try to) is: the more modern the API, the more declarative I'd want to manage it in code. Cloud APIs tend to sit on the most-declarative end of the spectrum and end-user workstations on the least-declarative (or: most-imperative) end.
While I have a couple of personal devices where I could go and customise everything as much as I like, it wouldn't port over to anyone I work with or any system I write software for, or any presentation I give, documentation I write etc.
Being more portable gives be better results overall than being specifically tailored to my preferences. I do default to light foreground and dark background colours wherever I go, but that is supported everywhere as far as I know, and has been the default on many platforms for long enough. (that said, I sometimes consult for complex/crazy situations and whenever you spot an xterm with black-on-white you know it's pain 'o clock).
Examples (including dead products and random tools you might not always put in the same league):
Aqua over GNOME3, GNOME3 over DWM/Windows, DWM/Windows over KDE, KDE over non-DWM/Windows Terminal.app over gnome-terminal over iTerm2 over urxvt over xterm over Windows Terminal over CMD.exe Sublime Text over Atom over vim over BBEdit over VSCode over nano over Notepad++ IntelliJ over Xcode over NetBeans over KDevelop over Eclipse over Visual Studio Safari over FireFox over Chromium over Chrome over Edge over Edgeium bash over zsh over csh over powershell over command.com Postgres over FoundationDB over MySQL over MongoDB over SQLite over Neo4J Terraform over SaltStack over Ansible over Chef over Puppet over PS DSC AWS over GCP over Azure Slack over IRC over Matrix over Signal over smoke signals over tin cans with a string over not communicating at all over MS Teams Kubernetes over Nomad over CloudRun over ECS over systemd units over Swarm