Duplicate resource declaration using parametrized class override

Hi all,

I’m hitting a bug somewhat similar to this:

I have a parametrized class that I use on one of my node. Everything works just fine at first.
When I go to the class configuration and use the smart parameter override however, I get a duplicate resource declaration:

Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Error while evaluating a Resource Statement, Evaluation Error: Error while evaluating a Resource Statement, Duplicate declaration: Class[Apt] is already declared; cannot redeclare at /srv/puppet/environments/production/manifests/apt.pp:2 at /srv/puppet/environments/production/manifests/apt.pp:2:5 on node somenode

I am definitely sure I did not change that Apt class or anything relevant to it.
Simply disabling the override makes the error disappear.

Thanks!
carlm

How are you including apt in apt.pp? Overriding it via the ENC is effectively equal to:

class { 'apt':
  param => value,
}

If your code also overrides it then you do get duplicate resources. You can include it:

include apt

The recommended solution is to apply the roles/profiles pattern. Designing Puppet – Roles and Profiles. does a good job but here’s the essence of how to apply it with an ENC rather than hiera:

image

The node is what Foreman defines. The role is in essence the host with its puppet classes including those added via host groups. The classes you add should be profile modules only. They are designed to be included as composable units and abstract away the lower level modules. In software engineering you’d call this business logic and it’s how you(r company) applies puppet modules.

The modules (bad name) are reusable modules, for example directly from the forge. They abstract away the lower level modules in higher level components. For example the apache module manages all aspects of apache (but nothing more).

Foreman should not touch modules and resources.

I’d suggest having one profiles module or various profile_* modules and then apply a filter as described in the manual. Modify /usr/share/foreman/config/ignored_environments.yml to include (change it if you use profile_*):

:filters:
  - !ruby/regexp '/^(?!profiles::)/'

That way Foreman will never import classes from modules other than profiles.

I know this is a very brief introduction into Managing Servers Using Puppet and Foreman. It’s also only one way of many and you need to find one that works for you.

1 Like

My bad maybe I wasn’t really clear.

The apt class just works fine. I have a module ‘foo’ with an init class which has parameters:

    class foo (
        $a = 'somestuff'
    ) inherits foo::params {
        # Some stuff
    }

That module is assigned to a node (let’s call it node1).
Going to Foreman, Configure Classes menu, and the smart parameter tab of the foo class, I can override the variable a. When doing so, and running puppet on node1, while previously the run worked fine, this time I get a totally unrelated duplicate resource declaration in another class that I didn’t modify.

I hope this is clearer.