[chef] Re: Compile time order


Chronological Thread 
  • From: Daniel DeLeo < >
  • To:
  • Subject: [chef] Re: Compile time order
  • Date: Mon, 7 Nov 2011 08:07:36 -0800



On Monday, November 7, 2011 at 7:43 AM, 

 wrote:

> Hi All,
> 
> I'm rather new Chef but already impressed with its power.
> For my current Chef investigations I need some way to put recipe at the 
> end of recipes list ignoring the real order of it in node's run_list.
> I'm working on automated firewall configuration and now using attribute 
> files of recipes to declare what ports this recipe needs to be opened. 
> "Firewall" recipe then parses all ports at compile time and creates 
> initial data for a template. But if I declare settings not in attribute 
> file but in recipe itself (via node.default/node.set) - then this change 
> is invisible to "firewall" recipe because it is already compiled. My 
> thoughts were to have some callback at the end of compile time or a way 
> of putting dynamically some code at the end of run_list (without saving 
> it to node state) - so "firewall" recipe declared elsewhere could put 
> callback and read the final attributes state.
> 
> Maybe there is some workaround to do this, or I need to change logic 
> completely to fit to current Chef run model?
> 
> wbr,
> Dmitry.

This happens because node attributes get recomputed and produce a new object 
when you read them, so when you modify an attribute later it does not affect 
the previously computed value.

One way to handle this use case is to modify the variables passed in to a 
template:

template "/path/to/file" do
  variables || variables(:tcp_ports => [])
  variables[:tcp_ports] << 80 << 443
end

# elsewhere:
template "/path/to/file" do
  variables || variables(:tcp_ports => [])

  variables[:tcp_ports] << 8000 << 8080
end

In case it's not clear, what's happening here is: when you declare a resource 
with the same type and "name argument" (i.e., argument passed in before 
`do`), chef will monkey patch the existing resource instead of creating a new 
one. What the variables lines are doing is setting the variables to a default 
setting ( `{:tcp_ports => [] }` if not already set, then adding the desired 
ports to the array.

Clearly there's more than a little duplication here, so you might want to 
wrap this up in a resource definition 
(http://wiki.opscode.com/display/chef/Definitions).

That said, it might be better to restructure your recipes and roles so that 
the required ports will be known ahead of time. But if that's not an option, 
you can make it work using the above.

-- 
Dan DeLeo






Archive powered by MHonArc 2.6.16.

§