How to pass value from one resource to another resource in chef recipe?
Your problem is that the code
variable is set during the compile phase of chef, before the ruby block has changed the value of your attribute. You need to add a lazy initializer around your code block.
Chef::Log.info("I am in #{cookbook_name}::#{recipe_name} and current disk count #{node[:oracle][:asm][:test]}")
bash "beforeTest" do
code lazy{ "echo #{node[:oracle][:asm][:test]}" }
end
ruby_block "test current disk count" do
block do
node.set[:oracle][:asm][:test] = "#{node[:oracle][:asm][:test]}".to_i+1
end
end
bash "test" do
code lazy{ "echo #{node[:oracle][:asm][:test]}" }
end
The first block doesn't really need the lazy, but I threw it in there just in case the value is changing elsewhere too.
pass variables from a chef resouce to other resources in the same chef recipe
Since you are running some Ruby code to get the file contents, you can even do it outside Chef resources. Something like:
if File.exists?("/work/customer/Var.js")
var = File.read("/work/customer/Var.js")
end
http_request 'cusromer update' do
action :put
# rest of code
end
Note that I've used var
with lower case v
.
Explanation:
The chef-client goes through several phases during the run. The two relevant for this answer are:
- Compile
- Converge
All variable and resources are compiled and assignments happen in the compile phase. So var
remains unassigned as there is no definition in for it in compile phase. Whereas ruby_block
and http_request
run in the converge phase.
How to pass variable between Chef resource blocks of same recipe
UUID is part of filesystem2
Ohai data:
filesystem2:
by_device:
/dev/md1:
...
uuid: f49a3dc8-a0b6-4e1c-8cd3-926fa7d8ee29
There is no need to run blkid
for this.
However, if you really need to do compute something in a block and use it later, you could declare uuid
variable before the block and use ruby_block
instead. You can also use node variable inside a ruby block. Anyway, you will be affected by Chef's two pass model and it would require further workarounds (like lazy attributes).
There is also a option to use helper method, but since UUID is part of Ohai data, I do not see any reason to even try (in this case).
Passing variables between chef resources
You have already solved problem A with the Ruby block.
Now you have to solve problem B with a similar approach:
ruby_block "create user" do
block do
user = Chef::Resource::User.new(node[:var], run_context)
user.shell '/bin/bash' # Set parameters using this syntax
user.run_action :create
user.run_action :manage # Run multiple actions (if needed) by declaring them sequentially
end
end
You could also solve problem A by creating the file during the compile phase:
execute "echo 'echo stuff' > /usr/local/bin/stuff.sh" do
action :nothing
end.run_action(:run)
If following this course of action, make sure that:
/usr/local/bin
exist during Chef's compile phase;- Either:
stuff.sh
is executable; OR- Execute it through a shell (e.g.:
var=`sh /usr/local/bin/stuff.sh`
How to pass variables in Chef recipe
It seems you are looking for string/variable interpolation. Chef attributes are same as variables in programming languages like Ruby.
String interpolation in Ruby is performed by using "#{}"
syntax. Any variable/attribute within the curly braces will be interpolated.
So your remote_file
resource should look like this:
remote_file "/tmp/docker-#{node['common']['docker']}.tgz" do
source "https://download.docker.com/linux/static/stable/x86_64/docker-#{node['common']['docker']}.tgz"
owner 'root'
group 'root'
mode '0755'
action :create
end
Note that I have used outer double quotes "
as it is required for interpolation. Also I have included the destination path as /tmp
to save the file.
Passing the value from a ruby block to a resource in chef
You can use lazy attribute like below:-
Chef::Log.info("Updating WLSADMIN Password")
passwd_backup 'Updating wlsadmin password' do
action :update_wlsadmin
osuser node[:password][:wls_config_user]
usergroup node[:password][:wls_install_group]
new_wls_password lazy { JSON.parse(File.read("/tmp/password.json"))['rase_wlsadmin_pwd'] }
end
Template resource can be written as:-
template "#{Chef::Config[:file_cache_path]}/domain.properties" do
source 'domain_properties.erb'
variables (lazy{{ :domain_name => "#{domain_name}",
:admin_url => "#{admin_url}",
:new_wls_password => JSON.parse(File.read("/tmp/password.json"))['rase_wlsadmin_pwd'] }})
end
Output:-
* template[/tmp/kitchen/cache/domain.properties] action create
- create new file /tmp/kitchen/cache/domain.properties
- update content in file /tmp/kitchen/cache/domain.properties from none to fa22e0
--- /tmp/kitchen/cache/domain.properties 2017-01-12 03:30:13.002968715 +0000
+++ /tmp/kitchen/cache/.chef-domain20170112-11387-1ytkyk2.properties 2017-01-12 03:30:13.002968715 +0000
@@ -1 +1,4 @@
+domain_name= mmm
+admin_url= nnn
+new_wls_password= xH#3zIS9Q4Hc#B
how to pass parameter to execute in chef?
The main issue is the use of single quotes (''
) in the command
. Single quotes in Ruby don't allow for interpolation of the variable #{execf}
. You should rewrite it as:
execute 'e.sh' do
command "/tmp/e.sh #{execf}"
action :nothing
end
However variable assignment (such as execf="e1"
) in the file
resources will not have any effect. You will get something like haha 2022-05-13 22:04:48
in the logs.
Edit
However variable assignment (such as
execf="e1"
) in thefile
resources will not have any effect.
Turns out that the variable assignment from within resource is also compiled, and last assigned value is used.
Related Topics
Rails 6: Only One Profile Per User Should Be Created
Getting Error (Exit Code 2) for Bootsnap, Not Allowing to Set Up Rails Server
Ruby on Rails - Paperclip Not Saving to Database
How to Combination/Permutation in Ruby
How to Reinstall Ruby with Readline Support
Searching from a Range of Ids in Activerecord
How to Create Alias to Attributes in Ruby
Why Does Ruby Use Its Own Syntax for Safe Navigation Operator
What Does "File.Sync = True" Do
Can You Have Multiple Versions of a Gem in a Gemfile
Quote All Fields in CSV Output
Split Float into Integer and Decimals in Ruby
How to Effectively Force Minitest to Run My Tests in Order
Carrierwave and Correct File Extension Depending on Its Contents
Rails Adding Multiple Objects to an Empty Array
Uml Sequence Diagram - How to Represent Method Arguments That Instantiate Objects
Ruby- Delete a Value from Sorted (Unique) Array at O(Log N) Runtime