How to alter a recipe in the simplest, DRYest way?

Hi all,

I’m new to Chef (but not to Opscode—hi guys!). I’m having trouble
discerning the One Right Way to Do It. Here’s a simple example: I
want to use NginxHttpRealIpModule. This entails compiling Nginx with
–with-http_realip_module. Being at the very beginning of my Chef
odyssey, I’ve not yet set up any Roles, so I create site-cookbooks/
nginx/attributes/nginx.rb, with these contents:

 set[:nginx][:configure_flags] = [
   "--prefix=#{nginx[:install_path]}",
   "--conf-path=#{nginx[:dir]}/nginx.conf",
   "--with-http_ssl_module",
   "--with-http_gzip_static_module",
   "--with-http_realip_module"
 ]

I’m using Chef 0.7.16. Since cookbook_path is [ “/srv/chef/site-
cookbooks”, “/srv/chef/cookbooks” ], I’d expect that this would set
[:nginx][:configure_flags], and its value would not be overwritten by
the Opscode cookbook attribute setting:

 set_unless[:nginx][:configure_flags] = [
   "--prefix=#{nginx[:install_path]}",
   "--conf-path=#{nginx[:dir]}/nginx.conf",
   "--with-http_ssl_module",
   "--with-http_gzip_static_module"
 ]

But when I install my recipes, execute chef-client on a node that has
nginx::source in its run list, and watch it recompile Nginx, it uses
the default value of configure_flags.

My next stab is to try to use a Role. So, I create roles/web-server.rb:

 name "web-server"

 description "Test role for configuring Web servers"

 recipes "nginx::source"

 override_attributes(
   "nginx" => {
     "configure_flags" => [
         "--prefix=#{nginx[:install_path]}",
         "--conf-path=#{nginx[:dir]}/nginx.conf",
         "--with-http_ssl_module",
         "--with-http_gzip_static_module",
         "--with-http_realip_module"
     ]
   }
 )

and run rake roles. This gives:

 undefined local variable or method `nginx' for #<Chef::Role: 

0x7fc810f37b60>

because the first two compiler flag definitions reference a Node
variable, and there’s no Node yet. I don’t know how to reference the
value of the install_path or dir defined in cookbooks/nginx/attributes/
nginx.rb from this Role. (I don’t even want to do that; the DRY thing
would be to simply append the one flag I need to configure_flags, but
there’s no syntax for that.)

So neither of the obvious (to me) ways to add a simple custom compiler
flag to the standard nginx::source recipe works.

Before I wholesale copy the nginx cookbook into site-cookbooks and
alter one line: what fundamental truth am I failing to discern here?

Thanks in advance,

Roger

Hi Roger!

On Sun, Apr 25, 2010 at 9:41 AM, Roger Rohrbach roger@ecstatic.com wrote:

But when I install my recipes, execute chef-client on a node that
has nginx::source in its run list, and watch it recompile Nginx, it uses the
default value of configure_flags.
My next stab is to try to use a Role. So, I create roles/web-server.rb:
name "web-server"
description "Test role for configuring Web servers"
recipes "nginx::source"
override_attributes(
"nginx" => {
"configure_flags" => [
"--prefix=#{nginx[:install_path]}",
"--conf-path=#{nginx[:dir]}/nginx.conf",
"--with-http_ssl_module",
"--with-http_gzip_static_module",
"--with-http_realip_module"
]
}
)

A role is the best approach to this, but the role itself isn't aware
of the 'nginx' attribute when it is compiled into JSON. You should
hardset the --prefix with the install_path you want to use.

"--prefix=/opt/nginx"

Or similar.

--
Opscode, Inc
Joshua Timberman, Senior Solutions Engineer
C: 720.878.4322 E: joshua@opscode.com

Joshua,

Thanks. I'll try that. But I humbly submit that Chef can do
better. DRY, DRY, DRY. It'd be great to have syntax like:

 append_attribute "nginx" => {"configure_flags" =>  "--with- 

http_realip_module"}

(That's probably not what it'd look like, but you get the idea.)

R.

Hi Roger!

On Sun, Apr 25, 2010 at 9:41 AM, Roger Rohrbach roger@ecstatic.com
wrote:

But when I install my recipes, execute chef-client on a node that
has nginx::source in its run list, and watch it recompile Nginx, it
uses the
default value of configure_flags.
My next stab is to try to use a Role. So, I create roles/web-
server.rb:
name "web-server"
description "Test role for configuring Web servers"
recipes "nginx::source"
override_attributes(
"nginx" => {
"configure_flags" => [
"--prefix=#{nginx[:install_path]}",
"--conf-path=#{nginx[:dir]}/nginx.conf",
"--with-http_ssl_module",
"--with-http_gzip_static_module",
"--with-http_realip_module"
]
}
)

A role is the best approach to this, but the role itself isn't aware
of the 'nginx' attribute when it is compiled into JSON. You should
hardset the --prefix with the install_path you want to use.

"--prefix=/opt/nginx"

Or similar.

--
Opscode, Inc
Joshua Timberman, Senior Solutions Engineer
C: 720.878.4322 E: joshua@opscode.com

Always remember Chef is ruby.

I have a site-cookbook nginx cookbook with attribute file

include_attribute "nginx::nginx" #make sure of the load order
node[:nginx][:configure_flags] << "--with-http_stub_status_module" #add

--Gilles

On Sun, Apr 25, 2010 at 10:09 AM, Roger Rohrbach roger@ecstatic.com wrote:

Joshua,

Thanks. I'll try that. But I humbly submit that Chef can do better. DRY,
DRY, DRY. It'd be great to have syntax like:

append_attribute "nginx" => {"configure_flags" =>
"--with-http_realip_module"}

(That's probably not what it'd look like, but you get the idea.)

R.

Hi Roger!

On Sun, Apr 25, 2010 at 9:41 AM, Roger Rohrbach roger@ecstatic.com
wrote:

But when I install my recipes, execute chef-client on a node that
has nginx::source in its run list, and watch it recompile Nginx, it uses
the
default value of configure_flags.
My next stab is to try to use a Role. So, I create roles/web-server.rb:
name "web-server"
description "Test role for configuring Web servers"
recipes "nginx::source"
override_attributes(
"nginx" => {
"configure_flags" => [
"--prefix=#{nginx[:install_path]}",
"--conf-path=#{nginx[:dir]}/nginx.conf",
"--with-http_ssl_module",
"--with-http_gzip_static_module",
"--with-http_realip_module"
]
}
)

A role is the best approach to this, but the role itself isn't aware
of the 'nginx' attribute when it is compiled into JSON. You should
hardset the --prefix with the install_path you want to use.

"--prefix=/opt/nginx"

Or similar.

--
Opscode, Inc
Joshua Timberman, Senior Solutions Engineer
C: 720.878.4322 E: joshua@opscode.com

Ah, brilliant! Thanks, Gilles. It was, like, my first day using
Chef...

On May 8, 2010, at 7:51 PM, Gilles Devaux wrote:

Always remember Chef is ruby.

I have a site-cookbook nginx cookbook with attribute file

include_attribute "nginx::nginx" #make sure of the load order
node[:nginx][:configure_flags] << "--with-http_stub_status_module"
#add

--Gilles

On Sun, Apr 25, 2010 at 10:09 AM, Roger Rohrbach
roger@ecstatic.com wrote:

Joshua,

Thanks. I'll try that. But I humbly submit that Chef can do
better. DRY,
DRY, DRY. It'd be great to have syntax like:

append_attribute "nginx" => {"configure_flags" =>
"--with-http_realip_module"}

(That's probably not what it'd look like, but you get the idea.)

R.