How do I define a resource only if it is not already defined?

asked 2017-03-22 14:45:14 -0600

madsa gravatar image

I am attempting to create a puppet module for managing secure configurations for CentOS. As part of this I want to manage different resources such as files, packages, and services, but only if they are not already managed. I want the puppet code to follow this algorithm:

  1. If the resource is not defined already and the file doesn't already exist on disk then do nothing.
  2. If the resource is not defined but does exist on disk then define a resource to manage it.
  3. If the resource is already defined then we should use a collector to apply attributes we want to set on the file resource.

Below is an example resource definition I have created that I thought would work if the ordering setting on the puppet agent is set to 'manifest'. In that case the declarations should be evaluated in order. What I expect to happen is that the first collector is hit which causes all definitions of the file to be evaluated if they exist. After that I check if the file resource is defined and create it if it doesn't exist already and the file is on disk. While this seemed to work in smaller manifests that I created to test this, it didn't work in actual production code. What ended up happening is that the file resource definition in this code was evaluated before the definition in a third party module which caused a duplicate declaration failure.

Is this even possible to do with Puppet?

NOTE: The 'file_exists' function is some Ruby code that just does a File.file? check and returns a boolean value.

define myfile (
  Boolean $executable = false,
) {
  $mode = $executable ? {
    true    => '0700',
    default => '0600',

  File<| title == $title |>

  $params = {
    ensure => present,
    owner  => 'root',
    group  => 'root',
    mode   => $mode,

  if !defined(File[$title]) and file_exists($title) {
    file { $title:
      * => $params,
  } else {
    File<| title == $title |> {
      * => $params,
edit retag flag offensive close merge delete


`ensure_resource` from `stdlib`.

Kai Burghardt gravatar imageKai Burghardt ( 2017-03-23 01:39:51 -0600 )edit

If you manage some of the resources with standard resource definitions, even ensure_resource will run into the same problems as a `!defined` if block, it depends on execution/parse order (NOT resource order).

DarylW gravatar imageDarylW ( 2017-03-23 07:56:52 -0600 )edit