Set attribute from recipe


#1

Hi,

I need to set an attribute (value) from default recipe.
Here is the code that I have and it works on my lab.

CentOS 6.4
Chef Server: chef-server-11.0.8-1.el6.x86_64
Chef Client: 11.4.4

attributes/default.rb
default[‘yum’][‘epel’][‘url’] = "http://
#{node[‘yum_srv_ip’]}/epel/6/#{node[‘kernel’][‘machine’]}"
default[‘yum’][‘epel’][‘enabled’] = 1

recipes/default.rb
nodes = search(“node”, “recipe:rm-yum-srv AND
chef_environment:#{node.chef_environment}”)
node.default[‘yum_srv_ip’] = nodes.first[‘ipaddress’]
Chef::Log.info(“20 YUM_SRV_IP: #{node[‘yum_srv_ip’]}”)
Chef::Log.info(“20 LOOKUP: #{nodes.first[‘ipaddress’]}”)
Chef::Log.info(“20 ENV: #{node.chef_environment}”)

The problem becomes when I try to compile that same code in different
environment (set of servers)
yum_srv_ip is empty and URL can’t be built, however I can see the value
printed to console ( Chef::Log from recipe )

CentOS 6.3
Chef Server: chef-server-11.0.4-1.el6.x86_64
Chef client: 11.4.0

Any idea where to have a look ?

Thanks


#2

General programming best practice comes into play here: If you add a
dependency on something outside of your code, you need to design for the
possibility that it won’t be available when you need it.

In this case, I think you’re building the URL in the attribute file (which
gets read relatively early on in the Chef run), but it depends on an
attribute that gets set a bit later (in the recipe compile phase). This is
the kind of thing that pops up right away if you always do all your recipe
testing on a brand-new node, but it may have been hidden depending on how
you developed the recipe.

So, things to try:

  • Set a default value for node[‘yum_srv_ip’] in the attribute file.
  • Move the EPEL URL definition from the attribute file into the recipe.
  • Consider what happens when your search returns no results. More
    precisely, what do you want to have happen? Should it raise an exception
    and halt the Chef run? Should it use a default value instead? Should it
    skip the resource until the search starts returning at least one valid
    search result?
  • Whatever you decided in the above thought exercise, implement that. If
    you’re at a loss, Google should be your friend on this one - I’m pretty
    sure there are Chef code examples of all of the above.

Hope this helps.

On Sun, Nov 3, 2013 at 4:40 AM, D.A. avsharyan@gmail.com wrote:

Hi,

I need to set an attribute (value) from default recipe.
Here is the code that I have and it works on my lab.

CentOS 6.4
Chef Server: chef-server-11.0.8-1.el6.x86_64
Chef Client: 11.4.4

attributes/default.rb
default[‘yum’][‘epel’][‘url’] = "http://
#{node[‘yum_srv_ip’]}/epel/6/#{node[‘kernel’][‘machine’]}"
default[‘yum’][‘epel’][‘enabled’] = 1

recipes/default.rb
nodes = search(“node”, “recipe:rm-yum-srv AND
chef_environment:#{node.chef_environment}”)
node.default[‘yum_srv_ip’] = nodes.first[‘ipaddress’]
Chef::Log.info(“20 YUM_SRV_IP: #{node[‘yum_srv_ip’]}”)
Chef::Log.info(“20 LOOKUP: #{nodes.first[‘ipaddress’]}”)
Chef::Log.info(“20 ENV: #{node.chef_environment}”)

The problem becomes when I try to compile that same code in different
environment (set of servers)
yum_srv_ip is empty and URL can’t be built, however I can see the value
printed to console ( Chef::Log from recipe )

CentOS 6.3
Chef Server: chef-server-11.0.4-1.el6.x86_64
Chef client: 11.4.0

Any idea where to have a look ?

Thanks