How can I change a file with Chef?
Asked Answered
P

4

29

I have 7 files and 1 war. I need to change values when I deploy them. I have this:

##usuario
#alfresco.user=*****
alfresco.user=********
##pass 
#alfresco.password= sfsfs
alfresco.password=sfgsf

alfresco.rutaAnexos=/gthtfdh/dfgdf/cm:

#atributo.type.anexo=ANEXO_INFO_OBJETO
atributo.type.anexo=AN
atributo.type.observaciones=OBSERVACIONES

I need to comment some lines and uncomment some other lines. Then I need to make seven templates and put variables depending on the environments and create a file in the recipe.

How can I do this?

Puerilism answered 13/2, 2013 at 6:58 Comment(1)
See docs.opscode.com/essentials_cookbook_templates.html and docs.opscode.com/resource_template.html, how templates work.Adultery
I
82

Chef actually allows and uses this. You can find an example in the opscode's

cookbooks/chef-server/recipes/default.rb:

ruby_block "ensure node can resolve API FQDN" do
  block do
    fe = Chef::Util::FileEdit.new("/etc/hosts")
    fe.insert_line_if_no_match(/#{node['chef-server']['api_fqdn']}/,
                               "127.0.0.1 #{node['chef-server']['api_fqdn']}")
    fe.write_file
  end
  not_if { Resolv.getaddress(node['chef-server']['api_fqdn']) rescue false }
end

Here's the use-case. After the installation from source I had to uncomment lines in some created configuration file that hadn't been the same in all versions of software, therefore use of templates hadn't been appropriate. The methods I used were:

  • (Object) search_file_replace(regex, replace)
  • (Object) search_file_replace_line(regex, newline)

You may find the full documentation here:

TO STRESS: This method is to be used only when using templates and partials is inappropriate. As @StephenKing already said, templates are common way of doing this.

It answered 3/10, 2013 at 19:0 Comment(11)
Sure, you can do it this way, but I strongly argue that putting whole files in place is best-practice compared to edigting them. I guess you see it when you compare your code with using a template resource.Adultery
@Adultery if it's so, I'd like you to answer my question: If you have 7 versions of software, each having differences in configuration file, and in that file, you have to set some core configuration that never changes, would you put 7 files in the template? Or you would use this method to uncomment 3 lines of code, and make your chef cookbook universal?It
@StephenKing, if you have some way I haven't thought of, please provide it here. I think that this kind of arguing would bring benefit to the entire topic. Besides, I agree, that method I provided should be used carefully, and only in the case of the unavoidable need.It
I wasn't arguing, I try to argument. One idea: pass the parts of your template that do change as variables to your template and decide about the version specific content in a recipe. Other idea: Try partial templates: docs.opscode.com/…Adultery
@Konzula Thanks for this answer. I just start using Chef but I find it also weird they favour replacing whole files. I would like to be given options rather than having the only one and 'right' way.Sixtasixteen
Good one! Partials are great, and makes the life easier. Still, I think file editing is sometimes necessary. PS. When I said "arguing" I didn't think anything bad. Sorry I misused the expression. @Peter, thanks :)It
This is a really good answer since right now i want to edit a file that is created by the OS, so, i can't create templates about it. AWESOME Answer man! Way better than the accepted one :|Anthotaxy
Yep, templates (or pushing raw content into a File resource) are great if Chef is generating the whole installation. But mediawiki (for example) generates its own LocalSettings.php file. Your choice is to 1) run the mediawiki init script and then add some edits to the generated LocalSettings.php file, or 2) reinvent the wheel, create the whole LocalSettings.ini file from a template and figure out how to create the databases structure, etc.Wherewithal
A major downside of editing files is ensuring the process is idempotent. This can be non-trivial! Use a template and that "just works."Wherewithal
In many cases a template is the right answer, but if you are managing the configuration of a software that you want to upgrade periodically and you don't want to have to recreate a "gold master" after every upgrade, using partial FileEdits is much better than installing and configuring the software manually or partially automated just to get the new settings fields/etc.Combings
Also, their usage has moved out of the default.rb into the helpers.rb. github.com/chef-cookbooks/chef-server/blob/master/libraries/…Combings
H
17

Here is an example of how you can use Chef to uncomment a line in a configuration file. The ruby_block is protected with a ::File::grep. The test for Debian is just for fun.

pam_config = "/etc/pam.d/su"
commented_limits = /^#\s+(session\s+\w+\s+pam_limits\.so)\b/m

ruby_block "add pam_limits to su" do
  block do
    sed = Chef::Util::FileEdit.new(pam_config)
    sed.search_file_replace(commented_limits, '\1')
    sed.write_file
  end
  only_if { ::File.readlines(pam_config).grep(commented_limits).any? }
end if platform_family?('debian')
Heise answered 7/2, 2014 at 16:26 Comment(1)
Can anyone explain how commented_limits works here, as related to a typical RegEx replace?Vieva
C
7

As of 2020, the solutions provided are discouraged - see here and here.

The modern way of performing file manual editing is to use the official, community-maintained, cookbook line.

Example:

replace_or_add "why hello" do
  path "/some/file"
  pattern "Why hello there.*"
  line "Why hello there, you beautiful person, you."
end

It's crucial, before using such strategy, to be 100% sure that manual editing is really required, but this is strictly dependent on the use case.

Cableway answered 17/9, 2020 at 8:12 Comment(0)
A
-5

By design, you don't modify files with Chef. Instead you put placeholders (<%= ..%>) into the file templates, which are then replaced with the dynamic values (so called attributes).

Adultery answered 13/2, 2013 at 8:11 Comment(2)
What if the file is also edited by another software? Templates are great, but there is need for editing files too (even ansible has lineinfile module).Cover
Then see the answer below.Adultery

© 2022 - 2024 — McMap. All rights reserved.