Search code examples
deploymentpuppet

Puppet: write a repo resource but include it in multiple places without duplication


I'm writing a puppet module for my application, and from some days I'm stuck on how to manage the repo.

I have puppet 4.10 and all the nodes are Centos 7

The init.pp file in the module of my application is:

 class my_app{
   anchor { '::my_app::begin': } ->
   class { '::my_app::repo': } ->
   class { '::my_app::install': } ->
   class { '::my_app::config': } ->
   class { '::my_app::service': } ->
   anchor { '::my_app::end': }
}

and the repo.pp class is:

class my_app::repo{
  if ! defined(Yumrepo[my_app]) {
    yumrepo {'my_app' :
      ensure   => 'present',
      descr    => 'my_app RPM repository',
      baseurl  => 'http://my_repo_server.com/repos/my_app',
      gpgcheck => 0
    }
  }
}

The init.pp class is installed on all the servers, now the problem is that all the clients and maybe also some servers needs also to have the my_app_client.pp:

class my_app::my_app_client{
  include my_app::repo
  [...]
}

The code returns an error is already declared because I declared the class my_app::repo twice.

I don't think that define 2 repo definitions in this case is correct, and declare it as Defined Resource Types doesn't seem to work either.

How should I resolve this issue? What is the good practice in this case?

Thanks in advance.


Solution

  • The problem here is that you can't use

    class { '::my_app::repo': }
    

    and

    include my_app::repo
    

    in the same set of manifests.

    The documentation for this is at https://puppet.com/docs/puppet/5.3/lang_classes.html#declaring-classes. The upshot is that you can only use a resource-like declaration (so, class) once for each class and you can't mix it with include, but you can include a class as many times as you like.

    In your case, I'd suggest you refactor to use include throughout for your my_app classes.