Derived attributes and the wrapper development method


#1

Hi Chef Users mailing list,

I reached out on IRC regarding why derived attributes are not computed, even though the parent attribute gets correctly wrapped and overwritten.

I was directed to these two fantastic links, that illuminate what has been the source of a large amount of frustration in performing Chef development for me:

https://coderanger.net/derived-attributes/

Does anyone know if there is development work from Opscode currently ongoing to make the wrapper development method a functional methodology?

Is there a facility / is there work currently under development to support env attributes in a role cookbook? That way you could properly test changes in a staged C/I workflow without instantly promoting changes to production.

Thanks all,
Joseph Hammerman


#2

Making wrappers is fine, you just need to be cognizant of the code you are writing. There is no general fix for this problem because it’s a fundamental issue of code ordering. As for attribute promotion, you might want to check out Policyfiles and poise-hoist for that workflow.


#3

Thanks coderanger.

I understand and am sympathetic to your viewpoint, but what do you think most users will make of code that renders different outputs from one run to the next? Isn’t idempotency supposed to be a pillar of the Chef development model?

Regarding PolicyFIles, do you know they fit into the development roadmap for OpsCode? A year ago, a coworker of mine told me that they are the future of development for Chef, but last week at the AWS Summit, an OpsCode representative told him to forget that he ever knew they existed.

Thanks,
Joseph Hammerman


#4

I see nothing wrong with wrappers at all and its probably in use in the majority of organizations using chef.

All the derived issues come from doing things like

original cookbook
node.default[‘namespace’][‘value’] = ‘potatoes’

wrapper cookbook
node.default[‘namespace’][‘value’] = 'whatever’
node.default[‘namespace’][‘newvalue1’] = 'this’
node.default[‘namespace’][‘newvalue2’] = 'that’
node.default[‘namespace’][‘ultimate_value’] = node[‘namespace’][‘newvalue1’] + node[‘namespace’][‘value’]

you’ll find the wrapper behaving very oddly…

but all you really should do is just set this properly… even if you ‘repeat’ your values somewhat…
node.default[‘namespace’][‘ultimate_value’]

its really a niche thing to have issues with… most folks wont ever run into it… if you’re not that deep into things yet… you’ll see most things will fit quite nicely… its only when taking short cuts that things behave oddly

even then you can use a code block to set those values as expected


#5

HI nukepuppy,

The issue is that I have no control over the upstream cookbook. I want to maintain upstream compatibility, but overriding every derived attribute in a wrapper makes my wrapper super fragile. In your example, often those intermediate values are used for an assortment of computed objects.

When you say “use a code block” do you mean reopen the compiled object in Ruby? Because then you are still dependent on particular variable names and structures implemented in the wrapped cookbook. That makes my codebase no more robust.

If I had to guess, I would imagine that the majority of Chef users probably fork and run local codebases, but I’ll defer to you.

For the record, this isn’t about taking shortcuts, it’s about building something reliable and easy to maintain, from my perspective :slight_smile:
Joseph Hammerman


#6

Forking is definitely not common in successful chef deployments.

All you have described is standard practice though. Depend on upstream cookbook and set the appropriate attributes to define the default behavior in the wrapper.

Do you have any examples of where you have had actual issues ?

Lots of wrapper cookbooks sometimes work by just setting a few default attributes… other can tie multiple upstream cookbooks and invoke as needed… I’ve never encountered an attribute issue that couldn’t be solved in a trivial manner.