Search code examples
rubychef-infrachef-recipe

Chef: Read variable from file and use it in one converge


I have the following code which downloads a file and then reads the contents of the file into a variable. Using that variable, it executes a command. This recipe will not converge because /root/foo does not exist during the compile phase.

I can workaround the issue with multiple converges and an

if File.exist

but I would like to do it with one converge. Any ideas on how to do it?

execute 'download_joiner' do
  command "aws s3 cp s3://bucket/foo /root/foo"
  not_if { ::File.exist?('/root/foo') }
end

password = ::File.read('/root/foo').chomp

execute 'join_domain' do
  command "net ads join -U joiner%#{password}"
end

Solution

  • You can download the file at compile time by using run_action and wrap the second part in the conditional block which will be executed at run time.

    execute 'download_joiner' do
      command "aws s3 cp s3://bucket/foo /root/foo"
      not_if { ::File.exist?('/root/foo') }
    end.run_action(:run)
    
    if File.exist?('/root/foo')
      password = ::File.read('/root/foo').chomp
    
      execute 'join_domain' do
        command "net ads join -U joiner%#{password}"
      end
    end