1

I have a cookbook that is being used to deploy some software on a chef nodes. I use it when bootstraping a node and then remove it from the run_list since I need it only to run once. I don't know if it's proper to do thing like that in Chef or if it's an antipattern. But this cookbook needs to have some variables that change on every node. Let's say that it needs to know the name of the main network interface of that node and I need to provide to it some kind of license number. I do that by using attributes, I specify in attributes/default.rb:

default['cookbook_name']['interface'] = 'eth0'
default['cookbook_name']['license'] = 'abcxyz'

And then I upload this to chef-server and run recipe on a node that is using this attributes. But if the other person wants to deploy the same software using this cookbook on some other node, then he needs to wait until I finish because if he will replace those values in attributes.rb with values of second node and upload it to chef-server then it will overwrite values that I need right now.

What is the proper way to do that? I feel like I am missing something about the work flow of attributes. As far as I see, using data bags will not solve the problem. Is there some way to assign "attribute" only to a specific node? Can I assign an attribute only to a given node?

  • Just do knife node edit and set the attributes on the node. It’s really easy once you’ve done it once. Chef is idempotent (more or less) so running the same recipe again should be fine too. – Gaius May 21 at 21:44
  • Thanks Gaius, it seems like what I was looking for :) – Learner May 22 at 6:27
  • 1
    Note also that you can knife node show -F json, load the JSON into e.g. Python, manipulate it, then write it back out and update the node that way... – Gaius May 22 at 10:34
0

You may use attributes precedence for that or a wrapper cookbook, I highly encourage you to take some time to check out https://learn.chef.io which cover those uses cases.

This is a kind of antipattern, one shot configuration are not what Chef is for, but for this use case I'd go with a common cookbook doing what is needed and a wrapper cookbook defining the attributes and including the common recipe.

A typical wrapper cookbook would need a few files:

  • metadata.rb as another cookbook with a line depends 'common_cookbook'
  • attributes\default.rb with the values for this type of server, same syntax as in common_cookbook
  • recipes\default.rb with the line include_recipe 'common_cookbook'

This pattern is also known as role cookbooks, more details in this blog post

  • Thanks! Really glad to learn about the wrapper cookbooks, since I want to do things according to "legal" patterns et cetera. Although I suspected that using recipe for doing things only once (deploying some app for example) is actually an antipattern. – Learner May 22 at 6:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.