In puppet is there any way to don’t realize virtual resources with collections, only with realize

puppet

In puppet it's possible to realize virtual resources with the realize function or with collections.

I'd like to know if it's possible to realize resources only with the realize function. As a simplified example, I'd want that with the followig manifest nginx is not installed, unless including nginx_conf module, that contains an implicit realize.

@package { 'nginx':
  ensure => present,
}

class nginx_conf {
  realize Package['nginx']

  file { '/etc/nginx/conf.d/foo':
    ensure => present,
    require => Package['nginx'],
  }
}

exec { 'apt-get update': path => '/usr/bin' }

Exec['apt-get update'] -> Package <| |>

Any idea?

An option is to put the package inside a separate class that is required by the module that is going to realize it, but I'd like to know if there is some way to select virtual resources in collections only if they are realized, and don't realize them only by being included in collections.

Best Answer

There doesn't seem to be a complete way to prevent Package <| |> from realizing resources. This could be a partial solution:

@package { 'nginx':
  ensure  => present,
  tag     => optional,
  require => Exec['apt-get update'],
}

Exec['apt-get update'] -> Package <| tag != optional |>

You would have to define requirements for each virtual Package, then.

The underlying problem can be solved, though, by using Run Stages:

class update-apt {
  exec { 'apt-get update': path => '/usr/bin' }
}

stage { 'first': before => Stage['main'] }
class {'update-apt':
  stage => 'first',
}

All classes and resources are run in the main-Stage by default, so Exec['apt-get update'] is always run before any Package-resources.

Related Topic