Problem with chef recipe run order

This is bizarre - though it may be my lack of understanding of chef :slight_smile:
Anyone know what might cause this behaviour?

We have a Base role, which looks like this:
“run_list”: [

“recipe[syslog-ng]”,

]

And a more specific role, OurSite which looks like:
“run_list”: [
“role[Base]”,

“recipe[syslog-ng::prod-web]”
]

The runlist for the node looks like:
“run_list”: [ “role[OurSite]” ]

Now, I was expecting that the default “recipe[syslog-ng]” would be
getting run quite early on.
It has a “not_if” statement on a cookbook_file, which causes it to
skip because we later want to use the syslog-ng::prod-web in this
specific role.

BIZARRE THING:
The syslog-ng isn’t run until the syslog-ng::prod-web recipe is supposed to run.
I’ve verified this by moving syslog-ng::prod-web up and down in the
run_list and watching the debug output in chef-client.
And when the not_if kicks in, in the default recipe, the more specific
syslog-ng::prod-web isn’t even run.

Help? I’m guessing this is happening because both recipes reference
the same cookbook_file, but that doesn’t explain why the run for the
syslog-ng::default is delayed until much later, and why both recipes
aren’t run.

I’ve included the pertinent bits of the recipes below.

syslog-ng::default:
cookbook_file “/etc/syslog-ng/syslog-ng.conf” do
not_if "grep ‘SPECIAL CONFIG’ /etc/syslog-ng/syslog-ng.conf"
source "genericv2.conf"
owner "root"
group "root"
mode 00644
notifies :restart, resources(:service => “syslog-ng”)
end

syslog-ng::prod-web
cookbook_file “/etc/syslog-ng/syslog-ng.conf” do
backup false
source "prodweb-syslog-ng.conf"
owner "root"
group "root"
mode 00644
notifies :restart, resources(:service => “syslog-ng”)
end

(sorry for the top post - short and probably more appropriate)

I think I found the cause here:
chef - [chef] Re: chef resources inherit not_if and only_if from previous copies
The idempotent nature of not_if is causing the problem to appear.

When I looked at the debug output and saw the not_if being applied in
the syslog-ng::prod-web recipe, I assumed the ::default recipe was not
being run until later.
I'm not sure if this is the case or not yet (it shouldn't be, but..).
The not_if statement was being carried forward which resulted in this.

:slight_smile:

On Tue, Feb 22, 2011 at 3:48 PM, Avleen Vig avleen@gmail.com wrote:

This is bizarre - though it may be my lack of understanding of chef :slight_smile:
Anyone know what might cause this behaviour?

We have a Base role, which looks like this:
"run_list": [
....
"recipe[syslog-ng]",
....
]

And a more specific role, OurSite which looks like:
"run_list": [
"role[Base]",
....
"recipe[syslog-ng::prod-web]"
]

The runlist for the node looks like:
"run_list": [ "role[OurSite]" ]

Now, I was expecting that the default "recipe[syslog-ng]" would be
getting run quite early on.
It has a "not_if" statement on a cookbook_file, which causes it to
skip because we later want to use the syslog-ng::prod-web in this
specific role.

BIZARRE THING:
The syslog-ng isn't run until the syslog-ng::prod-web recipe is supposed to run.
I've verified this by moving syslog-ng::prod-web up and down in the
run_list and watching the debug output in chef-client.
And when the not_if kicks in, in the default recipe, the more specific
syslog-ng::prod-web isn't even run.

Help? I'm guessing this is happening because both recipes reference
the same cookbook_file, but that doesn't explain why the run for the
syslog-ng::default is delayed until much later, and why both recipes
aren't run.

I've included the pertinent bits of the recipes below.

syslog-ng::default:
cookbook_file "/etc/syslog-ng/syslog-ng.conf" do
not_if "grep 'SPECIAL CONFIG' /etc/syslog-ng/syslog-ng.conf"
source "genericv2.conf"
owner "root"
group "root"
mode 00644
notifies :restart, resources(:service => "syslog-ng")
end

syslog-ng::prod-web
cookbook_file "/etc/syslog-ng/syslog-ng.conf" do
backup false
source "prodweb-syslog-ng.conf"
owner "root"
group "root"
mode 00644
notifies :restart, resources(:service => "syslog-ng")
end

Right - the issue is that the resources have the same name, which
means you are inheriting the not_if.

You can turn this:

syslog-ng::default:
cookbook_file "/etc/syslog-ng/syslog-ng.conf" do
not_if "grep 'SPECIAL CONFIG' /etc/syslog-ng/syslog-ng.conf"
source "genericv2.conf"
owner "root"
group "root"
mode 00644
notifies :restart, resources(:service => "syslog-ng")
end

syslog-ng::prod-web
cookbook_file "/etc/syslog-ng/syslog-ng.conf" do
backup false
source "prodweb-syslog-ng.conf"
owner "root"
group "root"
mode 00644
notifies :restart, resources(:service => "syslog-ng")
end

Into this:

syslog-ng::default:
cookbook_file "/etc/syslog-ng/syslog-ng.conf" do
source "genericv2.conf"
owner "root"
group "root"
mode 00644
notifies :restart, resources(:service => "syslog-ng")
end

syslog-ng::prod-web
cookbook_file "/etc/syslog-ng/syslog-ng.conf" do
source "prodweb-syslog-ng.conf"
end

And you'll get the effect you are looking for. The resource will get
applied where it appears first in the run list, which is in the
"syslog-ng" recipe.

Adam

On Tue, Feb 22, 2011 at 4:26 PM, Avleen Vig avleen@gmail.com wrote:

(sorry for the top post - short and probably more appropriate)

I think I found the cause here:
chef - [chef] Re: chef resources inherit not_if and only_if from previous copies
The idempotent nature of not_if is causing the problem to appear.

When I looked at the debug output and saw the not_if being applied in
the syslog-ng::prod-web recipe, I assumed the ::default recipe was not
being run until later.
I'm not sure if this is the case or not yet (it shouldn't be, but..).
The not_if statement was being carried forward which resulted in this.

:slight_smile:

On Tue, Feb 22, 2011 at 3:48 PM, Avleen Vig avleen@gmail.com wrote:

This is bizarre - though it may be my lack of understanding of chef :slight_smile:
Anyone know what might cause this behaviour?

We have a Base role, which looks like this:
"run_list": [
....
"recipe[syslog-ng]",
....
]

And a more specific role, OurSite which looks like:
"run_list": [
"role[Base]",
....
"recipe[syslog-ng::prod-web]"
]

The runlist for the node looks like:
"run_list": [ "role[OurSite]" ]

Now, I was expecting that the default "recipe[syslog-ng]" would be
getting run quite early on.
It has a "not_if" statement on a cookbook_file, which causes it to
skip because we later want to use the syslog-ng::prod-web in this
specific role.

BIZARRE THING:
The syslog-ng isn't run until the syslog-ng::prod-web recipe is supposed to run.
I've verified this by moving syslog-ng::prod-web up and down in the
run_list and watching the debug output in chef-client.
And when the not_if kicks in, in the default recipe, the more specific
syslog-ng::prod-web isn't even run.

Help? I'm guessing this is happening because both recipes reference
the same cookbook_file, but that doesn't explain why the run for the
syslog-ng::default is delayed until much later, and why both recipes
aren't run.

I've included the pertinent bits of the recipes below.

syslog-ng::default:
cookbook_file "/etc/syslog-ng/syslog-ng.conf" do
not_if "grep 'SPECIAL CONFIG' /etc/syslog-ng/syslog-ng.conf"
source "genericv2.conf"
owner "root"
group "root"
mode 00644
notifies :restart, resources(:service => "syslog-ng")
end

syslog-ng::prod-web
cookbook_file "/etc/syslog-ng/syslog-ng.conf" do
backup false
source "prodweb-syslog-ng.conf"
owner "root"
group "root"
mode 00644
notifies :restart, resources(:service => "syslog-ng")
end

--
Opscode, Inc.
Adam Jacob, Chief Product Officer
T: (206) 619-7151 E: adam@opscode.com

On Tue, Feb 22, 2011 at 4:38 PM, Adam Jacob adam@opscode.com wrote:

Right - the issue is that the resources have the same name, which
means you are inheriting the not_if.

You can turn this:

syslog-ng::default:
cookbook_file "/etc/syslog-ng/syslog-ng.conf" do
not_if "grep 'SPECIAL CONFIG' /etc/syslog-ng/syslog-ng.conf"
source "genericv2.conf"
owner "root"
group "root"
mode 00644
notifies :restart, resources(:service => "syslog-ng")
end

syslog-ng::prod-web
cookbook_file "/etc/syslog-ng/syslog-ng.conf" do
backup false
source "prodweb-syslog-ng.conf"
owner "root"
group "root"
mode 00644
notifies :restart, resources(:service => "syslog-ng")
end

Into this:

syslog-ng::default:
cookbook_file "/etc/syslog-ng/syslog-ng.conf" do
source "genericv2.conf"
owner "root"
group "root"
mode 00644
notifies :restart, resources(:service => "syslog-ng")
end

syslog-ng::prod-web
cookbook_file "/etc/syslog-ng/syslog-ng.conf" do
source "prodweb-syslog-ng.conf"
end

And you'll get the effect you are looking for. The resource will get
applied where it appears first in the run list, which is in the
"syslog-ng" recipe.

Thanks Adam :slight_smile:

I was concerned that doing this would cause the config to get replaced
twice (first with the generic, and then with the prodweb config) on
every chef run?

On Tue, Feb 22, 2011 at 4:48 PM, Avleen Vig avleen@gmail.com wrote:

Thanks Adam :slight_smile:

I was concerned that doing this would cause the config to get replaced
twice (first with the generic, and then with the prodweb config) on
every chef run?

Nope - if the resource has the same name, it will get re-opened and
updated with the new values - for precisely this use case.

If you did want it to get replaced, you would just change the name
of the second resource.

Adam

--
Opscode, Inc.
Adam Jacob, Chief Product Officer
T: (206) 619-7151 E: adam@opscode.com