Sorry for being so particular, but the phrases you're using could be addressed in many different ways. I can point you to a way that I've found helpful to automatically configure tools for my Jenkins instances. I'm not sure it is a preferred practice, or even a good practice, but it has worked quite well for me. Maybe that is what you're wanting.
I have a Docker instance defined at
https://github.com/MarkEWaite/docker/tree/lts-with-plugins/ref which includes automatically installed JDK 6, JDK 7, JDK 8, Maven, and Ant. I have many Jenkins jobs defined in that same Docker instance. Those jobs depend on the tools by symbolic name (JDK 6 == jdk6, JDK 7 == jdk7, JDK 8 == jdk8, Maven == mvn, Ant == ant-latest). When those jobs run, if they need a tool that is not already installed on the agent, the tool will be automatically installed. Thus far, the technique has worked quite well for my needs, with variations of that Docker instance being regularly used to check LTS release candidates, LTS releases, old releases, and new plugin release candidates.
Branches in that docker repository represent configurations that are interesting to me. There is an "lts" branch, an "lts-with-plugins" branch, and an lts-oldest-with-plugins. In a private repository I have "lts-with-plugins-add-credentials" and "lts-with-plugins-add-credentials-and-nodes" and others. That collection of branches allow me to rapidly switch from exploring and testing one variant or another.
Thanks,
Mark Waite