It looks like the issue here is that the kibana cookbook has a default recipe which does not have lazy {}
modifiers around its use of the node['kibana']['apache']['basic_auth_username']
and password node attributes.
It looks like there's a lot of work being done here to lazy everything and use a ruby_block
for reasons that I don't understand. A better approach would be to simply not use a ruby_block:
file = File.read('/opt/config/baselogging.json')
data = JSON.parse(file)
node.default['kibana']['apache']['basic_auth_username'] = data['KibanaUser']
node.default['kibana']['apache']['basic_auth_password'] = data['KibanaPassword']
include_recipe 'kibana'
If chef itself is responsible for generating baselogging.json
and you're trying to generate baselogging.json
and then read from baselogging.json
the solution I'd come up with would be to refactor and remove that:
data = ... stuff to populate the data ...
file "/opt/config/baselogging.json" do
content JSON.generate(data)
end
[...]
node.default['kibana']['apache']['basic_auth_username'] = data['KibanaUser']
node.default['kibana']['apache']['basic_auth_password'] = data['KibanaPassword']
include_recipe 'kibana'
Even if there's currently a remote_file
resource somewhere that creates baselogging.json you'd be better off doing something like this:
# "cheat" and download the file at compile-time
remote_file "/opt/config/baselogging.json" do
source "http://example.org/baselogging.json"
action :nothing
end.run_action(:create)
file = File.read('/opt/config/baselogging.json')
data = JSON.parse(file)
node.default['kibana']['apache']['basic_auth_username'] = data['KibanaUser']
node.default['kibana']['apache']['basic_auth_password'] = data['KibanaPassword']
include_recipe 'kibana'
The larger point here is that lazy {}
creates an arms race to lazying actions more and more and if you're consuming cookbooks outside of your control then it becomes uglier and uglier. The whole question has a lot of "code smell" that forcing stuff to happen later and later is winding up fighting how everything has been architected. You're better off going back and refactoring your assumptions so that you can move more work forwards in the chef run.
In general, you would try to compile all the information in your node attributes in the attributes file parsing phase. Setting attributes in recipe code leads to issues like this one and winds up where you find yourself wanting to submit PRs to every community cookbook in existence to lazy all of the attributes that they use. Using resource-driven library cookbooks instead of attribute-and-recipe driver library cookbooks can help sidestep this whole process. Barring that though you should assemble your node data early so that you do not have to lazy all the access to your node data.
If you must construct node data in recipe code then you must construct that data at compile time. Trying to set node data at recipe converge time is a symptom that you've gotten a bit lost.
ruby_block
is part of code that is executed after Resource Collecting so simply putinclude_recipe
outside this block as next step. – Serrate