Puppet requirement chains and partially satisfied conditions

At work we use (among other things) puppet to manage our server configurations. For those uninitiated, puppet provides a dsl for specifying server configurations. I won't go into details here, there are plenty of resources elsewhere.

Puppet works by specifying Resources, describing the desired state of the system. The provisioning of these is supposed to be idempotent, and each (regularly occurring) run makes sure the system is in the desired state.

The other day we spent quite a while debugging an unusual effect (bug?) in our puppet config. We use puppet 2.6.1 (can't upgrade at the moment) and had a resource manifest looking something like this:

user { foo-user:
    name => "foo-user",
    ensure => present,
}

file { [
    "/srv/foo/",
    "/srv/bar"]:
    ensure => directory,
    owner => foo-user,
    require => User[foo-user],
}

Running the puppet client threw us this helpful message

err: Could not run Puppet configuration client: Could not find user foo-user

No reference to any particular manifest files (usually puppet manifest errors reference file names and line numbers). After searching through all manifests for anything else that might reference this user and getting none the wiser, we finally resorted to gradually reducing our manifests down to a bare minimum. Occasionally we would get the client to run, though each case ended up being a false positive.

We finally managed to boil it down to the following:

If the target is partially satisfied, requirements are ignored.

In our case, it turned out that /srv/foo/ already existed, but foo-user and /srv/bar/ did not. We saw a similar behaviour when we had a longer chain of requirements.

A{ a:
    requires => B[b]
    # also requires C[c] but we assume this will be
    # taken care of via B[b]
}

B{ b:
    requires => C[c]
}

C{ c:
    # some user
}

In this case, if b is already satisfied but a and c are not, the puppet client fails with the rather unhelpful message above.

I hope this can save someone a few frustrating hours. Or at least that it will come up next time this happens to me (at which point I will no doubt have forgotten about this) and I'm frustratingly googling the error phrase above.

Comments !