Change node value in Chef-solo script at runtime

0

I'm trying to use Chef-solo to deploy some software inside a Vagrant VM, as well as be able to re-use the same recipes to deploy onto a Centos box running on EC2.

I'd prefer to generate the root MySQL password on the box rather than include it in the boot script. But how can I set a node value in Chef at runtime?

e.g. in the recipe below, the script buildInfo.php will write some JSON data into the file /etc/chef/serverInfo.json which I would then like Chef to read and use.

execute 'build_info' do
    cwd node[:source_folder] + "/tools"
    command  "php buildInfo.php /etc/chef/serverInfo.json"
    node.override.merge!(JSON.parse(File.read("/etc/chef/serverInfo.json")))
    command  "echo 'password is " + node["MYSQL_PASSWORD"] + "' > /tmp/chefvartest.txt"
end

However it seems that any command to change the values through node.override. etc. are done when Chef-solo starts up and parses the recipes, rather than when the recipes are actually run.

How can I set the value of a node variable like node["MYSQL_PASSWORD"] in one recipe, to be used later in a separate recipe?

Danack

Posted 2013-08-22T17:36:19.047

Reputation: 145

Answers

1

I actually found a way to do this by running a second Chef convergence after running through a couple things in a recipe. I'm surprised to see someone else needs this.

This is my write up of the re-convergence hack

Below is what I believe you need to accomplish this, please review the blog post too.

#some parts of your recipe can go up here

#Initialize a new chef client object
client = Chef::Client.new
client.run_ohai #you probably only need this if you need to get new data
client.load_node
client.build_node

#Intialize a new run context to evaluate later
run_context = if client.events.nil?
  Chef::RunContext.new(client.node, {})
else
  Chef::RunContext.new(client.node, {}, client.events)
end

#Initialize a chef resource that downloads the remote file
r = Chef::Resource::Execute.new("build_info", run_context)
r.cwd node[:source_folder] + "/tools"
r.command "php buildInfo.php /etc/chef/serverInfo.json"
r.run_action(:run)

#Converge and run the new resources
runner = Chef::Runner.new(run_context)
runner.converge

#Since the file is now created from the above hack, Chef will be able to read it
node.override.merge!(JSON.parse(File.read("/etc/chef/serverInfo.json")))

nictrix

Posted 2013-08-22T17:36:19.047

Reputation: 135