Why Puppet can require each package just once?

Solution 1:

You can use the ensure_resource() from stdlib module:

$packages = $::osfamily ? {
    'Debian' => [ 'fcgiwrap', ],
    'RedHat' => [ 'spawn-fcgi', 'git' ],
}
ensure_resource('package', $packages, {'ensure' => 'present'})

So, say, if git is installed by some other class already, that would be skipped. You should not care of defining a package only once throughout the puppet configuration.

Solution 2:

When you have duplicate packages, that's one way of dealing with it. The other way is to avoid the problem in the first place by using virtual resources:

Declaring a virtual resource

class packages {
  @package {
    ['cryptsetup-bin',
     'cryptsetup',
     'cifs-utils',
     'e2fsprogs',
     'libmysql-ruby',
     'parted',
     'pigz',
      'sshfs' ]:
        ensure => present,
    }
}

Realizing a virtual resource (you can realize resources multiple times):

include packages
realize Package['pigz']

Another approach is to separate out the duplicated code into another class - i.e. a 'wget' class.

Reference: Virtual Resource Puppet Doc