Cookbooks not running successfully in order for some reason


#1

HI all,

I’m experiencing a problem with cookbooks not running in order or at least not running successfully before the next cookbook on the list.

I have the following 3 cookbooks in a role in the following order:

  1. copies down the encrypted_data_bag_secret file via AWS CLI from an S3 bucket
  2. sets the local admin password (depends on #1)
  3. creates a new local account (depends on #1)

If run by itself, #1 works properly and copies the file to c:\chef\

As soon as I add #2 and/or #3 after it (and delete the file created from #1 to force it to rerun), #1 doesn’t copy the file and #2 and #3 fail.

The role has them in the order 1, 2, 3. I also added “include_recipe ‘get_secret’” to both #2 and #3 cookbooks as well as “depends ‘get_secret’” in their metadata.rb files.

Anyone have any ideas? Thanks a lot.


#2

I suspect a converge vs compile time evaluation problem.

'#2 or #3 does something at compile time relying on #1 being converged.

I’m on phone and can’t provide proper links, but search about chef two phases problem or compile vs converge time for more insight about it. (I’m pretty sure there’s an information on https://docs.chef.io, and I’m sure @coderanger has a blog post about it)

Next time, copy the error from chef run, it avoids the need of too much guessing


#3

That’s exactly what the problem is! Thank you for bringing it to my
attention. Now to figure out how to edit my code to work around it.


#4

According to your description I would do the copy in #1 at compile time, without an idea on how you do it it’s hard to advise better actually.

Usual way to run a resource at compile time is something like this:

resource "name" do
  parameter1 "value"
  parameter2 "value"
  action :nothing
end.run_action(:action)

This should be considered as last resort method, but for the use case of getting the secret key for databags it sounds the best idea.


#5

Here’s my code to download the file:

execute ‘get secret file’ do
command 'aws s3 cp s3://blahblahblah/secret/encrypted_data_bag_secret c:/chef/encrypted_data_bag_secret’
not_if { File.exist?(‘c:\chef\encrypted_data_bag_secret’ )}
end


#6

This should do:

if !::File.exist?('c:\chef\encrypted_data_bag_secret' )
  execute 'get secret file' do
    command 'aws s3 cp s3://blahblahblah/secret/encrypted_data_bag_secret c:/chef/encrypted_data_bag_secret'
    action :nothing
  end.run_action(:execute)
end

But to get files from S3 I recomend using the aws cookbook for it’s aws_s3_file resource like this:

aws_s3_file 'file:///c:/chef/encrypted_data_bag_secret' do
  bucket 'secret'
  path 'encrypted_data_bag_secret'
  action :nothing
end.run_action(:create)

And as reference the chef official documentation