Using Chef recipe, I am first generating a .erb file dynamically based on inputs from a CSV file and then I want to use that .erb file as a template source. But unfortunately the changes made (in .erb file) are not considered while the recipe is converging the resources. I also tried to use lazy evaluation but not able to figure out how to use it for the template source.
2 Answers
Quoting the template documentation:
sourceRuby Types: String, ArrayThe location of a template file. By default, the chef-client looks for a template file in the /templates directory of a cookbook. When the local property is set to true, use to specify the path to a template on the local node. This property may also be used to distribute specific files to specific platforms. See “File Specificity” below for more information. Default value: the name of the resource block. See “Syntax” section above for more information.)
And
localRuby Types: TrueClass, FalseClass
Load a template from a local path. By default, the chef-client loads templates from a cookbook’s /templates directory. When this property is set to true, use the source property to specify the path to a template on the local node. Default value: false.
so what you can do is:
# generate the local .erb file let's say source.erb
template "/path/to/file" do
source "/path/to/source.erb"
local true
end
Your question sounds like and XY problem, reading a csv file to make a template sounds counter-productive and could probably be done with attributes and taking advantage of the variable attribute of template resource.
Assuming you know how to capture the values from the CSV file as a local variable in the recipe.
Examples:
csv_hostname
csv_fqdn
Here is what you do to create a template with lazy loading attributes. The following example creates a config file.
example.erb file
# Dynamically generated by awesome Chef so don't alter by hand.
HOSTNAME=<% @host_name %>
FQDN=<% @fqdn %>
recipe.rb file
template 'path\to\example.config' do
source 'example.erb'
variables(
lazy {
:host_name => csv_hostname,
:fqdn => csv_fqdn
})
end
If you need it to run at compile time, add the action to the block.
template 'xxx' do
# blah blah
end.run_action(:create)