| Useful comments from Charlie Sharpsteen in Slack about the possible underlying cause and potential fixes on the apt/postgres module side: - `puppetlabs-postgres` is using a resource collector that is selecting packages via implicit tags in order to add an Apt repo as a dependency. This is working around the fact that we never got the implementation of run stages quite right, but the tags that resources inherit implicitly from their containing class behave in surprising ways that make them unreliable. - `puppetlabs-apt` is using `ensure_resource()` to make sure the `apt-transport-https` package is installed without taking explicit ownership of it — and thus conflicting with other modules or user code that may be managing the package. This is working around the fact that our duplicate resource rules are very strict and we don't allow for multiple definitions of a resource in cases where there is no conflict. The downside here is that `ensure_resource` has the effect of injecting `package { 'apt-transport-https': }` into whichever scope happens to use `apt::source` first which opens that resource up to having all sorts of unwanted defaults attached to it in a way that is extremely difficult to debug. Some potential solutions: - For `puppetlabs-postgresql`, make the requirement on the apt resource explicit where it is needed, or use an explicit tag for the collector that is not "magically" generated from the class namespace. Using the module's qualified name, `puppetlabs-postgres`, would make a better tag to set explicitly and then collect. - For `puppetlabs-apt`, it should probably just take explicit ownership and declare `package {'apt-transport-https': }` if that is required. This may conflict with other code, but "duplicate resource" errors are usually very good at pointing to where the problem is. In contrast, errors resulting from a package being injected into some random scope are a nightmare to track down and not something that can be done quickly by someone who has never seen this sort of issue before. Alternately, if `puppetlabs-apt` wants to use `ensure_resource()`, then it should do that inside a class owned by the module instead of a defined type so that the resource is contained in a very explicit spot and stops injecting its self into whatever happens to use `apt::source` first. |