Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a Chef recipe to append multiple lines to a config file

I'm trying to create a Chef recipe to append multiple lines (20-30) to a specific config file.

I'm aware the recommended pattern is to change entire config files rather than just appending to a file, but I dislike this approach for multiple reasons.

So far the only solution I found was to use a cookbook_file and then use a bash resource to do:

cat lines_to_append >> /path/configfile

Obviously this wouldn't work properly, as it'd append the file over and over, each time you run chef-client. I'd have to create a small bash script to check for a specific string first, and, if not found, append to the file.

But this seems to defeat the purpose of using Chef. There must be a better way.

One promising solution was the line cookbook from OpsCode Community. It aimed to solve this exact problem. Unfortunately the functionality is incomplete, buggy, and the code is just a quick hack. Far from being a solid solution.

Another option I evaluated was augeas. Seems pretty powerful, but it'd add yet-another layer of abstraction to the system. Overkill, in my case.

Given that this is one of the most obvious tasks for any sysadmin, is there any easy and beautiful solution with Chef that I'm not seeing?


EDIT: here's how I'm solving it so far:

 cookbook_file "/tmp/parms_to_append.conf" do
   source "parms_to_append.conf"
 end

 bash "append_to_config" do
   user "root"
   code <<-EOF
      cat /tmp/parms_to_append.conf >> /etc/config
      rm /tmp/parms_to_append.conf
   EOF
   not_if "grep -q MY_IDENTIFIER /etc/config"
 end

It works, but not sure this is the recommended Chef pattern.

like image 883
Gui Ambros Avatar asked Jun 02 '13 03:06

Gui Ambros


2 Answers

As you said yourself, the recommended Chef pattern is to manage the whole file.

If you're using Chef 11 you could probably make use of partials for what you're trying to achieve.

There's more info here and on this example cookbook.

As long as you have access to the original config template, just append <%= render "original_config.erb" %> to the top of your parms_to_append.conf template.

like image 91
cassianoleal Avatar answered Oct 10 '22 20:10

cassianoleal


Here is the example ruby block for inserting 2 new lines after match:

ruby_block "insert_lines" do
  block do
    file = Chef::Util::FileEdit.new("/etc/nginx/nginx.conf")
    file.insert_line_after_match("worker_rlimit_nofile", "load_module 1")
    file.insert_line_after_match("pid", "load_module 2")
    file.write_file
  end
end

insert_line_after_match searches for the regex/string and it will insert the value in after the match.

like image 42
Ranjith Kumar G Avatar answered Oct 10 '22 20:10

Ranjith Kumar G