How can I convert from erb file to my config file only in Chef?
I don't want to run the chef-client on the remote instance, but I want to convert the config.erb template file to a config file by interpolating the attributes from the chef.
I found this command, but usually people use this command to add attributes to the chef.
knife exec -E 'environments.transform("name:my_project") {|n| ..}'
      
        
        
        
      
    
So how do I run the knife command locally, but just convert the template erb file?
This is how I ended up. I created a script to use the ERB lib to translate the template with interpolation:
tran.rb:
require "erb"
input_file = "/var/lib/j.../config.ini.erb"
output_file = "/var/lib/.../config.ini"
content = File.open(input_file, 'rb').read
template = ERB.new(content)
class ERBContext
    def initialize(env)
        env.transform("name:#{myenv}") do |n|
            attrs = n.default_attributes["nap"]
            attrs.each do |key, value|
                instance_variable_set('@' + key.to_s, value)
            end
        end
    end
    def get_binding
        binding
    end
end
erb_context = ERBContext.new(environments)
config_file = template.result(erb_context.get_binding)
File.open(output_file, 'w+') do |f|
    f.write(config_file)
end
      
        
        
        
      
    
      Since knife exec only expects script files to set myenv variable, I need to call a command like this
(echo 'myevn = "xxxxxxxx"' ;  cat ./tran.rb) | sudo knife exec
      
        
        
        
      
     It seems strange to do this with a knife.
My best idea would be to start a chef with a "fake" client name to render the files locally and then move them around. This has been discussed under the heading "manage node".
You may have a config file managed.rb
      
        
        
        
      
    with an environment variable for client_name.
Sample file in /etc/chef/managed.rb file:
log_level                :info
log_location             STDOUT
node_name                ENV['node_name']
client_key               "/path/to/your/targets/keystore/#{ENV['node_name']}.pem"
chef_server_url          'https://chef-server-url.local'
      
        
        
        
      
    
      Then you can set this environment variable of node_name
      
        
        
        
      
    your target node, if you have validation key, it will create client and node object and will run locally.
In a cookbook, you can do something like:
target_dir="/opt/configs/#{node['chef_client']['config']['node_name']}"
directory target_dir do
  action :create
  recursive true
end
execute "copy to #{node['chef_client']['config']['node_name']}" do
  cmd "scp #{target_dir}/* #{node['chef_client']['config']['node_name']}:/etc"
  action :nothing # don't copy at each run if no config file has changed
end
template "#{target_dir}/my_conf" do
  source "my_conf.erb"
  action :create
  notifies :run, "execute[copy to #{node['chef_client']['config']['node_name']}]"
end
      
        
        
        
      
    
then you can call the chef like this in the crontab:
59 0 * * * root node_name="my-rp-XX" chef-client -c /etc/chef/managed.rb