Define an attribute with another attribute

Hi Team,

In my environment file, I have defined an attribute say ['app']['web'] = 'nginx' and in another environment file ['app']['web'] = 'apache'

My intention is to create a recipe which will run on any environment. Inside the recipe I'm defining one attribute. So while running this recipe in the first environment i want to define node.default['cluster']['nginx']['endpoint'] and in second environment it should be node.default['cluster']['apache']['endpoint']

I used the following

But this is not working. Is there any way I can achieve this ?

Unless you need to have both an nginx config and a apache config at the same time you can just use attribute and override it from your environment file.

Default['cluster']['endpoint'] = ''
In your environment file just do this to override the value, the name of the attribute doesn't really matter so much just the value of the attribute.
Override['cluster']['endpoint'] = 'new value'

You can also do

Default['cluster']['endpoint'] = node['cluster']['nginx']['endpoint']

To set the value of the cluster endpoint value to that of the nginx endpoint value.

It's going to depend on node['app']['web']. If you have

node['app']['web']['endpoint'], I suspect that node['app']['web'] isn't
just a string, but rather a hash. Easy to fix, but first, I'm not sure
precisely certain what you mean by apache and nginx. Are these just
human-friendly labels? Are they package names? Are they service names?

If they are the names of the actual packages, I'd do something like


or perhaps


if it's just the name of the desired service. Ensure that whichever you
choose is either going to be set to a string or something that can be
cast to a string.

Then try

node['cluster'][node['app']['web']['daemon']]['endpoint'] or even

Actual code that's similar and has worked (that probably has more
".to_s" than it needs).

node['jdk']['versions'].each do |key, value|



where these attributes are defined.

default['jdk']['packages']['debian'] = {
'oracle7' => {
'package' => 'oracle-j2sdk1.7',
'version' => '1.7.0+update55',
default['jdk']['packages']['rhel'] = {
'oracle7' => {
'package' => 'jdk',
'version' => '2000:1.7.0_55-fcs',

default['jdk']['versions'] = {
'oracle7' => true,

@kencrouch Thank you for your detailed update. I didn't fully understood about the .to_s method. I'm a beginner on this and apologize for that.

In the environment file I defined the attribute

"override_attributes": {

In recipe, defining the another attribute

node.default['cluster'][node['app']['web']]['endpoint'] = "somevalue"

But during the converge it failed to get the value of node['app']['web'] and throwing the error
undefined method `' for nil:NilClass

Could you let me know what modification I need to make inorder to work this

[theonlyjyothish] theonlyjyothish
December 6

@kencrouch Thank you for your
detailed update. I didn't fully understood about the .to_s method. I'm a
beginner on this and apologize for that.

Adding ".to_s" returns a string representation of your object. It can
sometimes force something that isn't what you intended to "work" enough
that you can see what's happening. :slight_smile:

node.default['cluster'][node['app']['web']]['endpoint'] = "somevalue"

instead of

node.default['cluster'][node['app']['web']]['endpoint'] = "somevalue"

try using something like

= "somevalue"

Basically, since you have


you might not want to use


as a string in the name of an attribute. Instead use

node['app']['web']['SOMETHING'] where SOMETHING could be 'name',
'package', 'daemon', 'service', 'whatever' (but not endpoint).