Search code examples
rubychef-infrachef-recipecookbook

chef recipe FileEdit insert_line_after_match and insert_line_if_no_match


I want to edit file using chef cookbook recipe. The file appears now as,

[attribute1]
foo=bar
[attribute2]
....

I want to change it like:

[attribute1]
foo=bar
newfoo=newbar
[attribute2]
....

So basically, I want to add a line if it does not exist in the file and I want to add it after a particular line in that file.

I found 2 options under Class: Chef::Util::FileEdit which could be useful here insert_line_after_match and insert_line_if_no_match. But I want an option which can perform both of the actions. If I use insert_line_after_match, it works for first run but for next run it just keep adding lines even if line is already in the file. And insert_line_if_no_match adds line at the end of file if line does not exist in file but I want to add line after particular line in that file.

I am bit new to chef recipes. Is there any solution to solve above problem?


Solution

  • I would suggest not editing files, but rather overwriting them. You should create a template or a file inside the cookbook and then using template or cookbook_file resource overwrite the file on the machine with the one from cookbook.

    Your config file looks similar to toml, so you can also use toml-rb gem to generate this file from json (data bag) or attributes like that:

    chef_gem 'toml-rb' do
      compile_time false
    end
    
    file '/path/to/file.conf' do
      content( lazy do
        require 'toml'
        "# This file is managed by Chef\n" +
        TOML.dump( my_json )
      end )
    end