Template attributes - converge time vs. run time


#1

I noticed when I pass attributes to a template resource via the 'variables’
attribute the attributes values are what they are at converge time. So if
I modify those attributes during the chef run, before the template resource
get’s called, it doesn’t matter. They get rendered as they were at
converge time.

The only way around this I’ve found is to NOT pass the attributes via the
’variables’ attribute and instead source them directly in the template. I
don’t like doing that. I like having everything that’s being passed to the
template defined in the recipe for documentation purposes.

Is there any way around this? The attribute is correct in memory at the
time the template resource is called. Is there any way to tell it to use
the attribute in memory instead of how it was at converge time? Or am I
stuck calling them from within the template?

MG


#2

I believe this http://docs.opscode.com/release_notes.html#lazy-attribute-evaluation is what you’re looking for.

–Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On Wednesday, October 16, 2013 at 21:16, Michael Glenney wrote:

I noticed when I pass attributes to a template resource via the ‘variables’ attribute the attributes values are what they are at converge time. So if I modify those attributes during the chef run, before the template resource get’s called, it doesn’t matter. They get rendered as they were at converge time.

The only way around this I’ve found is to NOT pass the attributes via the ‘variables’ attribute and instead source them directly in the template. I don’t like doing that. I like having everything that’s being passed to the template defined in the recipe for documentation purposes.

Is there any way around this? The attribute is correct in memory at the time the template resource is called. Is there any way to tell it to use the attribute in memory instead of how it was at converge time? Or am I stuck calling them from within the template?

MG


#3

On Wednesday, October 16, 2013 at 5:37 PM, Cassiano Leal wrote:

I believe this http://docs.opscode.com/release_notes.html#lazy-attribute-evaluation is what you’re looking for.

On Wednesday, October 16, 2013 at 21:16, Michael Glenney wrote:

I noticed when I pass attributes to a template resource via the ‘variables’ attribute the attributes values are what they are at converge time. So if I modify those attributes during the chef run, before the template resource get’s called, it doesn’t matter. They get rendered as they were at converge time.

The only way around this I’ve found is to NOT pass the attributes via the ‘variables’ attribute and instead source them directly in the template. I don’t like doing that. I like having everything that’s being passed to the template defined in the recipe for documentation purposes.

Is there any way around this? The attribute is correct in memory at the time the template resource is called. Is there any way to tell it to use the attribute in memory instead of how it was at converge time? Or am I stuck calling them from within the template?

MG
You can also use template helpers to keep your logic separate from your templates:

http://docs.opscode.com/resource_template.html#helpers


Daniel DeLeo


#4

This is interesting. What would be the difference between the two methods (lazy vs helper)?

–Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On Thursday, October 17, 2013 at 14:08, Daniel DeLeo wrote:

On Wednesday, October 16, 2013 at 5:37 PM, Cassiano Leal wrote:

I believe this http://docs.opscode.com/release_notes.html#lazy-attribute-evaluation is what you’re looking for.

On Wednesday, October 16, 2013 at 21:16, Michael Glenney wrote:

I noticed when I pass attributes to a template resource via the ‘variables’ attribute the attributes values are what they are at converge time. So if I modify those attributes during the chef run, before the template resource get’s called, it doesn’t matter. They get rendered as they were at converge time.

The only way around this I’ve found is to NOT pass the attributes via the ‘variables’ attribute and instead source them directly in the template. I don’t like doing that. I like having everything that’s being passed to the template defined in the recipe for documentation purposes.

Is there any way around this? The attribute is correct in memory at the time the template resource is called. Is there any way to tell it to use the attribute in memory instead of how it was at converge time? Or am I stuck calling them from within the template?

MG
You can also use template helpers to keep your logic separate from your templates:

http://docs.opscode.com/resource_template.html#helpers


Daniel DeLeo


#5

Awesome guys. Thanks! I went with the “lazy” method because it’s less
syntax but tried them both out and they both work.

Cassiano, I wondered the same thing. They looked the same. Almost as if
"lazy" was just an alias for the helper. From what I can see:

  1. Helper is much more powerful. Especially the way it can take
    arguments. I think the fact that it will allow you to use cookbook library
    modules is also unique.
  2. Helpers are limited to template resources whereas lazy can be used
    anywhere

Other then that they are very similar and I’ll be share some code.

It did prompt me to learn about "Lazy evaluation"
http://en.wikipedia.org/wiki/Lazy_evaluation which I didn’t know about
before so thanks for that :slight_smile:

Here’s what I ended up with which worked perfectly:

template “/etc/security/access.conf” do
source "access.conf.erb"
mode 0440
owner "root"
variables(
:access_groups => lazy { node[‘authorization’][‘access’][‘groups’] },
:access_users => lazy { node[‘authorization’][‘access’][‘users’] }
)
action :nothing
end

This resource exists purely to notify the above resource to run near the

end of the chef run
execute “true” do
notifies :create, ‘template[/etc/security/access.conf]’, :delayed
end

Thanks again !!

MG

On Thu, Oct 17, 2013 at 1:22 PM, Cassiano Leal cassianoleal@gmail.comwrote:

This is interesting. What would be the difference between the two methods
(lazy vs helper)?


Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On Thursday, October 17, 2013 at 14:08, Daniel DeLeo wrote:

On Wednesday, October 16, 2013 at 5:37 PM, Cassiano Leal wrote:

I believe this
http://docs.opscode.com/release_notes.html#lazy-attribute-evaluation is
what you’re looking for.

On Wednesday, October 16, 2013 at 21:16, Michael Glenney wrote:

I noticed when I pass attributes to a template resource via the
’variables’ attribute the attributes values are what they are at converge
time. So if I modify those attributes during the chef run, before the
template resource get’s called, it doesn’t matter. They get rendered as
they were at converge time.

The only way around this I’ve found is to NOT pass the attributes via the
’variables’ attribute and instead source them directly in the template. I
don’t like doing that. I like having everything that’s being passed to the
template defined in the recipe for documentation purposes.

Is there any way around this? The attribute is correct in memory at the
time the template resource is called. Is there any way to tell it to use
the attribute in memory instead of how it was at converge time? Or am I
stuck calling them from within the template?

MG

You can also use template helpers to keep your logic separate from your
templates:

http://docs.opscode.com/resource_template.html#helpers


Daniel DeLeo


#6

Hi Michael, i was having the same problem and ended up with lazy. But im
not using the notify to run the template resource near the end of chef run.
I think that you don’t need to do that when using lazy. Am i wrong?


Si necesitas una máquina para hacer algo y no la compras al final te darás
cuenta de que has pagado lo mismo y no tienes la máquina.–Henry Ford

Alberto

On Thu, Oct 17, 2013 at 9:36 PM, Michael Glenney mike.glenney@gmail.comwrote:

Awesome guys. Thanks! I went with the “lazy” method because it’s less
syntax but tried them both out and they both work.

Cassiano, I wondered the same thing. They looked the same. Almost as if
"lazy" was just an alias for the helper. From what I can see:

  1. Helper is much more powerful. Especially the way it can take
    arguments. I think the fact that it will allow you to use cookbook library
    modules is also unique.
  2. Helpers are limited to template resources whereas lazy can be used
    anywhere

Other then that they are very similar and I’ll be share some code.

It did prompt me to learn about "Lazy evaluation"
http://en.wikipedia.org/wiki/Lazy_evaluation which I didn’t know about
before so thanks for that :slight_smile:

Here’s what I ended up with which worked perfectly:

template “/etc/security/access.conf” do
source "access.conf.erb"
mode 0440
owner "root"
variables(
:access_groups => lazy { node[‘authorization’][‘access’][‘groups’] },
:access_users => lazy { node[‘authorization’][‘access’][‘users’] }
)
action :nothing
end

This resource exists purely to notify the above resource to run near the

end of the chef run
execute “true” do
notifies :create, ‘template[/etc/security/access.conf]’, :delayed
end

Thanks again !!

MG

On Thu, Oct 17, 2013 at 1:22 PM, Cassiano Leal cassianoleal@gmail.comwrote:

This is interesting. What would be the difference between the two methods
(lazy vs helper)?


Cassiano Leal
http://cassianoleal.com
http://twitter.com/cassianoleal

On Thursday, October 17, 2013 at 14:08, Daniel DeLeo wrote:

On Wednesday, October 16, 2013 at 5:37 PM, Cassiano Leal wrote:

I believe this
http://docs.opscode.com/release_notes.html#lazy-attribute-evaluation is
what you’re looking for.

On Wednesday, October 16, 2013 at 21:16, Michael Glenney wrote:

I noticed when I pass attributes to a template resource via the
’variables’ attribute the attributes values are what they are at converge
time. So if I modify those attributes during the chef run, before the
template resource get’s called, it doesn’t matter. They get rendered as
they were at converge time.

The only way around this I’ve found is to NOT pass the attributes via the
’variables’ attribute and instead source them directly in the template. I
don’t like doing that. I like having everything that’s being passed to the
template defined in the recipe for documentation purposes.

Is there any way around this? The attribute is correct in memory at the
time the template resource is called. Is there any way to tell it to use
the attribute in memory instead of how it was at converge time? Or am I
stuck calling them from within the template?

MG

You can also use template helpers to keep your logic separate from your
templates:

http://docs.opscode.com/resource_template.html#helpers


Daniel DeLeo