[chef] Fwd: Re: Newbie design related doubt


Chronological Thread 
  • From: Peter Burkholder < >
  • To:
  • Subject: [chef] Fwd: Re: Newbie design related doubt
  • Date: Mon, 3 Nov 2014 12:28:27 -0500


I can see where you're coming from with your concerns about configuration being scattered across multiple places. While Solution #2 keeps all of your logic in one place, you're making your cookbook code highly coupled to how your using environments, which may make it harder to refactor later.  This is where Conway's law comes into play: If you're the only person managing Chef, use #2. Otherwise, consider how you'll communicate about what your code is doing.

If you consider attributes as interfaces to which environments can pass messages, then you might want to approach Solution 1 as I've outlined below:
On Thu, Oct 30, 2014 at 9:13 AM, Tensibai < " target="_blank"> > wrote:

Le 2014-10-30 12:21, Varun Shankar a écrit :

I know that attributes can be configured in cookbooks (attribute files and recipes), roles, and environments. 
 
Suppose I have a requirement on the following lines:
- Two environments: alpha and beta
- Two web servers: web-1, web-2
- Apache should run on port 80 on web-1 in alpha
- Apache should run on port 8080 on web-2 in alpha
- Apache should run on port 8081 on web-1 and web-2 in beta
 
I can have two approaches:
SOLUTION 1. Write a role cookbook (using application/library pattern) and override the apache[listen_ports] attribute in the role cookbook. Again override the apache[listen_ports] attribute in my chef-repo/environments/alpha.rb and chef-repo/environments/beta.rb file. But this way the configuration for Apache is scattered in multiple places (environment files, role cookbooks and the apache community cookbook).
We'll write web1-app and web2-app cookbooks that, in turn use the 'apache' library cookbook. You can set attribute defaults for web1-app and web2-app cookbooks which act as their interface to the underlying apache resource:

cookbooks/web1-app/
  web1-role/attributes/default.rb:
    default['web1-role']['apache']['listen_port'] = 80 # use the alpha environment as the default settings
    default['apache']['listen_port'] = node['web1']['apache']['listen_port'] 

environments/beta.json:
  "default_attributes": {
    "web1-app": { 
      "apache" : {  "listen_port" : 8081 }
    },
    "web2-app": {
      "apache" : {  "listen_port" : 8081 }
    }
  }

And similarly for the web2-role. A few points on what we're doing here.

1. Yes, you have your configuration scattered, but you have decoupled the interfaces so you can add gamma and delta envs without touching your cookbook. If you don't use role attributes, and if you don't set attributes in recipe.rb files, then you have a clean path from env attributes, to application-cookbook attributes, to the underlying library attributes.
2. As long as you're not trying to put web1 and web2 on the same node, you have decoupled the listen_port attributes for those two roles
3. Because cookbook attributes are resolved in load order, and we first load the apache cookbook, then the web1-role cookbook, we only use the "default" attribute levels, saving "override" for potential edge cases.

Caveat: I have not tested the above code, and please feel free to poke holes in my approach.


 
SOLUTION 2. Write a wrapper cookbook over the community apache cookbook. In the attribute file of my wrapper cookbook, I write logic like this:
 
apache[listen_ports] = 8080
if env is alpha
  if role is web1
    apache[listen_ports] = 80
  elseif role is web2
    apache[listen_ports] = 8080
end
 
This way all apache settings are consolidated in one place i.e. in the cookbook.
 
I have seen all the blog posts suggest the first solution. Why is the second solution a bad idea? 
 

 




--



  • [chef] Fwd: Re: Newbie design related doubt, Peter Burkholder, 11/03/2014

Archive powered by MHonArc 2.6.16.

§