Problems with golden images are that you have to store a full system image with overhead of data which is not build-specific, and using conventions for configuration to make deploy process the same for all versions.
TL;DR: Infrastructure as a Code, version-specific storage for data outside the app package.
The problem is easily solved by storing config files and templates, data and installation scripts (including ansible playbooks to manage) inside both code and packages/images, so install and initial configuration would always be version-specific (switching to the same commit you are deploying to have configs you need). This could be done with VCS and current package management software (deb, msi, PKG etc. and scripts for unattended deploy and installation) with ease. To avoid using different images of OS and other environment, storing and using a single golden image for all builds is a standard practice: it provides consistency and you can automate CI/CD pipeline for image update process.
If some data is stored outside (i.e. a lot of current Windows apps outside of Store are installed by running a downloader, then installing app) and you have to keep large number of them (no specific branches only like stable-beta-alpha), then storage should be versioned too (i.e. using version-specific hashes as names) and links in install scripts or artifacts would point to the one version they need. But you also have to keep the register of pairs build:data version
, so when there's no need to use specific version, deletion of related data could be performed within the same remove process. Also, you have to decide whether you want to store complete images or use some differential systems (incremental or differential snapshots of files/filesystems), latter is much more complex and hard to manage so it's not used widely AFAIK (with an exception for some DBs, i.e. Facebook stores MySQLs snapshots and binary transaction logs so they could deploy or restore exact state up to certain transaction id).