tl;dr: Forget creating images. Use a configuration management system.
The moment you create an image (or only very slightly thereafter), your image is already out-of-date. Packages constantly get updated, vulnerabilities fixed, etc.
Instead of putting your time into pressing these "golden images", put your time into implementing your config in a proper configuration management system. Several very good free, open-source options are out there:
These systems allow you to specify how you want your systems to look, and then apply that configuration in an idempotent manner to the base OS image. Doing things this way ensures that deployed systems are always up-to-date. For packages where you need a certain version, you can specify in your configs that this package should be pinned at version X.
Additionally, you will not only get to streamline your new system deployment process, but also you'll be able to leverage the config management system for deploying changes across your fleet - systems that are already running. Want to change DNS servers? Just update a single line in your Puppet manifest, and that change will get deployed to all systems.
These systems have a non-trivial learning curve, but the benefits of deploying this way far outweigh the pain of not using a config management system.