Using env attr to override a default

hello. after many, many years of cfengine, i’m wading thru a learning
phase with chef, and loving it. bear with me while i get a handle on
this. i’m trying to override an attribute in the postfix cookbook using
an environment attribute. which cookbook it is doesn’t matter. it’s
something fundamental i’m trying to grasp, and this is a simple example.

let’s say for my prod environment i want my postfix clients to use a
certain mail relay, and for my dev environment i want them to use
another. in the postfix cookbook attributes (the lowest precedence), i
can set defaults.

it’s not working for me, and i’m wondering what i’m doing wrong. what i
expect to have on my mail client node is a relayhost of
mungbeans.dev.dorqtown.com, but what i’m getting is
mailrelay.dev.dorqtown.com.

first, the prod and dev environments:

[chef-repo]$ knife environment show dev
chef_type:            environment
cookbook_versions:    
default_attributes:  
  mail-client: 
    relayhost:  mungbeans.dev.dorqtown.com
  mail-server: 
    relayhost:  [smtp.gmail.com]:587
description:          Development environment (dev)
json_class:           Chef::Environment
name:                 dev
override_attributes:  


[chef-repo]$ knife environment show prod
chef_type:            environment
cookbook_versions:    
default_attributes:  
  mail-client: 
    relayhost:  mailrelay.prod.dorqtown.com
  mail-server: 
    relayhost:            [smtp.sendgrid.net]:587
    smtp_fallback_relay:  [smtp.gmail.com]:587
description:          Production environment
json_class:           Chef::Environment
name:                 prod
override_attributes:  

a test node’s run list:

[chef-repo]$ knife node show sous-chef1.dev.dorqtown.com -r
run_list: 
    role[base]
    role[dns-client]
    role[mail-client]
    role[syslog-ng-client]
    recipe[toolbin]


[chef-repo]$ knife role show mail-client -a run_list
run_list:             recipe[postfix]

so, above, we know the “default” recipe is implied. i could’ve written
this as recipe[postfix::default]. i wonder if this is biting me - in my
attributes dir, i only have mail-client.rb and mail-server.rb, not
default.rb. does that matter? i wonder how the chef-client run would
parse either of those if run_list isn’t recipe[postfix::mail-client] or
recipe[postfix::mail-server]. i’m misunderstanding something on the use
of the attributes dir. but let’s get to it:

the relayhost attribute:

[chef-repo]$ grep relayhost cookbooks/postfix/attributes/mail-client.rb
default[:postfix][:relayhost]  = "mailrelay.dev.dorqtown.com"

[chef-repo]$ grep relayhost cookbooks/postfix/attributes/mail-server.rb 
default[:postfix][:relayhost]  = "[smtp.gmail.com]:587"

a relevant portion of the template,
postfix/templates/default/main.cf.erb. do i need to add logic to the
template to first check for attribute coming from an env before the
cookbook attributes file?

<% if node[:postfix][:mail_type] == "mail-server" -%>
relayhost = <%= node[:postfix][:relayhost] %>
smtp_fallback_relay = <%= node[:postfix][:relayhost] %>
mynetworks = <%= node[:postfix][:mail_relay_networks] %>
inet_interfaces = all
<% else -%>
relayhost = <%= node[:postfix][:relayhost] %>
mynetworks = <%= node[:postfix][:mail_relay_networks] %>
inet_interfaces = localhost
<% end -%>

the resulting main.cf on a client:
###
# Generated by Chef for sous-chef1.dev.dorqtown.com
# Configured as mail-client
###
biff = no
append_dot_mydomain = yes
myhostname = sous-chef1.dev.dorqtown.com
mydomain = dev.dorqtown.com
myorigin = $myhostname
smtpd_banner = $myhostname ESMTP $mail_name
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = sous-chef1.dev.dorqtown.com, sous-chef1, localhost.localdomain, localhost
relayhost = mailrelay.dev.dorqtown.com
mynetworks = 127.0.0.0/8
inet_interfaces = localhost
mailbox_size_limit = 0
recipient_delimiter = +

above, i want the dev env attribute for relayhost, not the default one
from cookbooks/postfix/attributes/mail-client.rb.

and hmmm… my test node running the mail-server role kept picking up the
mail-client postfix config UNTIL i removed all attribute files from
cookbooks/postfix/attributes EXCEPT for server.rb. hmmm. clearly i need
to be schooled…

thanks a lot,
kallen

Yo,

Your environments attributes are wrong:

On 27 September 2011 17:49, kallen@groknaut.net wrote:

hello. after many, many years of cfengine, i'm wading thru a learning
phase with chef, and loving it. bear with me while i get a handle on
this. i'm trying to override an attribute in the postfix cookbook using
an environment attribute. which cookbook it is doesn't matter. it's
something fundamental i'm trying to grasp, and this is a simple example.

let's say for my prod environment i want my postfix clients to use a
certain mail relay, and for my dev environment i want them to use
another. in the postfix cookbook attributes (the lowest precedence), i
can set defaults.

it's not working for me, and i'm wondering what i'm doing wrong. what i
expect to have on my mail client node is a relayhost of
mungbeans.dev.dorqtown.com, but what i'm getting is
mailrelay.dev.dorqtown.com.

first, the prod and dev environments:

[chef-repo]$ knife environment show dev
chef_type: environment
cookbook_versions:
default_attributes:
mail-client:
relayhost: mungbeans.dev.dorqtown.com
mail-server:
relayhost: [smtp.gmail.com]:587
description: Development environment (dev)
json_class: Chef::Environment
name: dev
override_attributes:

this should be:
default_attributes "postfix" => { "relayhost" => "whatever" }

The attributes are deep merged together onto the node and thus the
atribute structure must remain the same. Does this make sense?

If you can post the on-disk, ruby version of the environment files I
can point out the problem, otherwise good luck!

–AJ

[chef-repo]$ knife environment show prod
chef_type: environment
cookbook_versions:
default_attributes:
mail-client:
relayhost: mailrelay.prod.dorqtown.com
mail-server:
relayhost: [smtp.sendgrid.net]:587
smtp_fallback_relay: [smtp.gmail.com]:587
description: Production environment
json_class: Chef::Environment
name: prod
override_attributes:

a test node's run list:

[chef-repo]$ knife node show sous-chef1.dev.dorqtown.com -r
run_list:
role[base]
role[dns-client]
role[mail-client]
role[syslog-ng-client]
recipe[toolbin]

[chef-repo]$ knife role show mail-client -a run_list
run_list: recipe[postfix]

so, above, we know the "default" recipe is implied. i could've written
this as recipe[postfix::default]. i wonder if this is biting me - in my
attributes dir, i only have mail-client.rb and mail-server.rb, not
default.rb. does that matter? i wonder how the chef-client run would
parse either of those if run_list isn't recipe[postfix::mail-client] or
recipe[postfix::mail-server]. i'm misunderstanding something on the use
of the attributes dir. but let's get to it:

the relayhost attribute:

[chef-repo]$ grep relayhost cookbooks/postfix/attributes/mail-client.rb
default[:postfix][:relayhost] = "mailrelay.dev.dorqtown.com"

[chef-repo]$ grep relayhost cookbooks/postfix/attributes/mail-server.rb
default[:postfix][:relayhost] = "[smtp.gmail.com]:587"

a relevant portion of the template,
postfix/templates/default/main.cf.erb. do i need to add logic to the
template to first check for attribute coming from an env before the
cookbook attributes file?

<% if node[:postfix][:mail_type] == "mail-server" -%>
relayhost = <%= node[:postfix][:relayhost] %>
smtp_fallback_relay = <%= node[:postfix][:relayhost] %>
mynetworks = <%= node[:postfix][:mail_relay_networks] %>
inet_interfaces = all
<% else -%>
relayhost = <%= node[:postfix][:relayhost] %>
mynetworks = <%= node[:postfix][:mail_relay_networks] %>
inet_interfaces = localhost
<% end -%>

the resulting main.cf on a client:

Generated by Chef for sous-chef1.dev.dorqtown.com

Configured as mail-client

biff = no
append_dot_mydomain = yes
myhostname = sous-chef1.dev.dorqtown.com
mydomain = dev.dorqtown.com
myorigin = $myhostname
smtpd_banner = $myhostname ESMTP $mail_name
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = sous-chef1.dev.dorqtown.com, sous-chef1, localhost.localdomain, localhost
relayhost = mailrelay.dev.dorqtown.com
mynetworks = 127.0.0.0/8
inet_interfaces = localhost
mailbox_size_limit = 0
recipient_delimiter = +

above, i want the dev env attribute for relayhost, not the default one
from cookbooks/postfix/attributes/mail-client.rb.

and hmmm.. my test node running the mail-server role kept picking up the
mail-client postfix config UNTIL i removed all attribute files from
cookbooks/postfix/attributes EXCEPT for server.rb. hmmm. clearly i need
to be schooled...

thanks a lot,
kallen

On Tue, 27 Sep 2011, AJ Christensen wrote:

Yo,

Your environments attributes are wrong:

On 27 September 2011 17:49, kallen@groknaut.net wrote:

first, the prod and dev environments:

[chef-repo]$ knife environment show dev
chef_type: environment
cookbook_versions:
default_attributes:
mail-client:
relayhost: mungbeans.dev.dorqtown.com
mail-server:
relayhost: [smtp.gmail.com]:587
description: Development environment (dev)
json_class: Chef::Environment
name: dev
override_attributes:

this should be:
default_attributes "postfix" => { "relayhost" => "whatever" }

The attributes are deep merged together onto the node and thus the
atribute structure must remain the same. Does this make sense?

If you can post the on-disk, ruby version of the environment files I
can point out the problem, otherwise good luck!

i can show you the json version of the env files. i was trying to
cobble together the ruby, but not getting it quickly. for the sake of
speed i'll show the json. i see what you're saying about attribute
structure, so i corrected it, i believe. but the client's relayhost
in main.cf is still picking up the setting from the postfix cookbook
attr setting rather than the dev env setting.

[chef-repo]$ cat environments/dev.json
{
"name": "dev",
"default_attributes": {
"postfix": {
"mail-server": {
"relayhost": "[outbound.mailhop.org],[smtp.gmail.com]:587"
},
"mail-client": {
"relayhost": "mungbeans.dev.dorqtown.com"
}
}
},
"json_class": "Chef::Environment",
"description": "Development environment (dev)",
"chef_type": "environment"
}

[chef-repo]$ knife node show sous-chef1.dev.dorqtown.com -r
run_list: role[mail-client]

[sous-chef1-dev ~]# grep relayhost /etc/postfix/main.cf
relayhost = mailrelay.dev.dorqtown.com

where to look?

silly question - are your nodes actually assigned to the different
environments?

You've shown that you've created the environments, and the nodes' run lists,
but not the nodes' environments.
see for manipulating node's env:
http://wiki.opscode.com/display/chef/Environments#Environments-SettingaNode'sEnvironment

On Tue, Sep 27, 2011 at 2:32 PM, kallen@groknaut.net wrote:

On Tue, 27 Sep 2011, AJ Christensen wrote:

Yo,

Your environments attributes are wrong:

On 27 September 2011 17:49, kallen@groknaut.net wrote:

first, the prod and dev environments:

[chef-repo]$ knife environment show dev
chef_type: environment
cookbook_versions:
default_attributes:
mail-client:
relayhost: mungbeans.dev.dorqtown.com
mail-server:
relayhost: [smtp.gmail.com]:587
description: Development environment (dev)
json_class: Chef::Environment
name: dev
override_attributes:

this should be:
default_attributes "postfix" => { "relayhost" => "whatever" }

The attributes are deep merged together onto the node and thus the
atribute structure must remain the same. Does this make sense?

If you can post the on-disk, ruby version of the environment files I
can point out the problem, otherwise good luck!

i can show you the json version of the env files. i was trying to
cobble together the ruby, but not getting it quickly. for the sake of
speed i'll show the json. i see what you're saying about attribute
structure, so i corrected it, i believe. but the client's relayhost
in main.cf is still picking up the setting from the postfix cookbook
attr setting rather than the dev env setting.

[chef-repo]$ cat environments/dev.json
{
"name": "dev",
"default_attributes": {
"postfix": {
"mail-server": {
"relayhost": "[outbound.mailhop.org],[smtp.gmail.com]:587"
},
"mail-client": {
"relayhost": "mungbeans.dev.dorqtown.com"
}
}
},
"json_class": "Chef::Environment",
"description": "Development environment (dev)",
"chef_type": "environment"
}

[chef-repo]$ knife node show sous-chef1.dev.dorqtown.com -r
run_list: role[mail-client]

[sous-chef1-dev ~]# grep relayhost /etc/postfix/main.cf
relayhost = mailrelay.dev.dorqtown.com

where to look?

On Tue, 27 Sep 2011, andi abes wrote:

silly question - are your nodes actually assigned to the different
environments?

not silly, cuz i do silly things sometimes. but i think my env is set
correctly:

test node which i desire to be a mail-client:
[sous-chef1-dev ~]# grep environment /etc/chef/client.rb
environment "dev"

again, mail-client should pick up the env override for relayhost
as "mungbeans.dev.dorqtown.com" instead of the default value from
the recipe attributes. but it's not.

test node which i desire to be a mail-server:
[sous-chef2-dev ~]# grep environment /etc/chef/client.rb
environment "dev"

in debug output, i do see it seeking out env info.
[Tue, 27 Sep 2011 18:15:50 +0000] DEBUG: Sending HTTP Request via POST to 10.2.7.238:4000/environments/dev/cookbook_versions
[Tue, 27 Sep 2011 18:15:51 +0000] DEBUG: Sending HTTP Request via GET to 10.2.7.238:4000/environments/dev

and fwiw, the chef clients are CentOS 5.6, running 0.10.4, RPMs
from RBEL (e.g. rubygem-chef-0.10.4-1.el5).

i'm running my own chef server, Ubuntu 11.04, 0.10.4-1.

You've shown that you've created the environments, and the nodes' run lists,
but not the nodes' environments.
see for manipulating node's env:
http://wiki.opscode.com/display/chef/Environments#Environments-SettingaNode'sEnvironment

On Tue, Sep 27, 2011 at 2:32 PM, kallen@groknaut.net wrote:

On Tue, 27 Sep 2011, AJ Christensen wrote:

Yo,

Your environments attributes are wrong:

On 27 September 2011 17:49, kallen@groknaut.net wrote:

first, the prod and dev environments:

[chef-repo]$ knife environment show dev
chef_type: environment
cookbook_versions:
default_attributes:
mail-client:
relayhost: mungbeans.dev.dorqtown.com
mail-server:
relayhost: [smtp.gmail.com]:587
description: Development environment (dev)
json_class: Chef::Environment
name: dev
override_attributes:

this should be:
default_attributes "postfix" => { "relayhost" => "whatever" }

The attributes are deep merged together onto the node and thus the
atribute structure must remain the same. Does this make sense?

If you can post the on-disk, ruby version of the environment files I
can point out the problem, otherwise good luck!

i can show you the json version of the env files. i was trying to
cobble together the ruby, but not getting it quickly. for the sake of
speed i'll show the json. i see what you're saying about attribute
structure, so i corrected it, i believe. but the client's relayhost
in main.cf is still picking up the setting from the postfix cookbook
attr setting rather than the dev env setting.

[chef-repo]$ cat environments/dev.json
{
"name": "dev",
"default_attributes": {
"postfix": {
"mail-server": {
"relayhost": "[outbound.mailhop.org],[smtp.gmail.com]:587"
},
"mail-client": {
"relayhost": "mungbeans.dev.dorqtown.com"
}
}
},
"json_class": "Chef::Environment",
"description": "Development environment (dev)",
"chef_type": "environment"
}

[chef-repo]$ knife node show sous-chef1.dev.dorqtown.com -r
run_list: role[mail-client]

[sous-chef1-dev ~]# grep relayhost /etc/postfix/main.cf
relayhost = mailrelay.dev.dorqtown.com

where to look?

Could you show the output of
knife node show yourmail-server
knife node show yourmail-server -a postfix
knife environment show dev
knife environment show prod

Are any of the roles setting the attributes? Here are the precedence
rules for reference:
http://wiki.opscode.com/display/chef/Attributes#Attributes-Precedence

Thanks,
Matt Ray
Senior Technical Evangelist | Opscode Inc.
matt@opscode.com | (512) 731-2218
Twitter, IRC, GitHub: mattray

On Tue, Sep 27, 2011 at 5:04 PM, kallen@groknaut.net wrote:

On Tue, 27 Sep 2011, andi abes wrote:

silly question - are your nodes actually assigned to the different
environments?

not silly, cuz i do silly things sometimes. but i think my env is set
correctly:

test node which i desire to be a mail-client:
[sous-chef1-dev ~]# grep environment /etc/chef/client.rb
environment "dev"

again, mail-client should pick up the env override for relayhost
as "mungbeans.dev.dorqtown.com" instead of the default value from
the recipe attributes. but it's not.

test node which i desire to be a mail-server:
[sous-chef2-dev ~]# grep environment /etc/chef/client.rb
environment "dev"

in debug output, i do see it seeking out env info.
[Tue, 27 Sep 2011 18:15:50 +0000] DEBUG: Sending HTTP Request via POST to 10.2.7.238:4000/environments/dev/cookbook_versions
[Tue, 27 Sep 2011 18:15:51 +0000] DEBUG: Sending HTTP Request via GET to 10.2.7.238:4000/environments/dev

and fwiw, the chef clients are CentOS 5.6, running 0.10.4, RPMs
from RBEL (e.g. rubygem-chef-0.10.4-1.el5).

i'm running my own chef server, Ubuntu 11.04, 0.10.4-1.

You've shown that you've created the environments, and the nodes' run lists,
but not the nodes' environments.
see for manipulating node's env:
http://wiki.opscode.com/display/chef/Environments#Environments-SettingaNode'sEnvironment

On Tue, Sep 27, 2011 at 2:32 PM, kallen@groknaut.net wrote:

On Tue, 27 Sep 2011, AJ Christensen wrote:

Yo,

Your environments attributes are wrong:

On 27 September 2011 17:49, kallen@groknaut.net wrote:

first, the prod and dev environments:

[chef-repo]$ knife environment show dev
chef_type: environment
cookbook_versions:
default_attributes:
mail-client:
relayhost: mungbeans.dev.dorqtown.com
mail-server:
relayhost: [smtp.gmail.com]:587
description: Development environment (dev)
json_class: Chef::Environment
name: dev
override_attributes:

this should be:
default_attributes "postfix" => { "relayhost" => "whatever" }

The attributes are deep merged together onto the node and thus the
atribute structure must remain the same. Does this make sense?

If you can post the on-disk, ruby version of the environment files I
can point out the problem, otherwise good luck!

i can show you the json version of the env files. i was trying to
cobble together the ruby, but not getting it quickly. for the sake of
speed i'll show the json. i see what you're saying about attribute
structure, so i corrected it, i believe. but the client's relayhost
in main.cf is still picking up the setting from the postfix cookbook
attr setting rather than the dev env setting.

[chef-repo]$ cat environments/dev.json
{
"name": "dev",
"default_attributes": {
"postfix": {
"mail-server": {
"relayhost": "[outbound.mailhop.org],[smtp.gmail.com]:587"
},
"mail-client": {
"relayhost": "mungbeans.dev.dorqtown.com"
}
}
},
"json_class": "Chef::Environment",
"description": "Development environment (dev)",
"chef_type": "environment"
}

[chef-repo]$ knife node show sous-chef1.dev.dorqtown.com -r
run_list: role[mail-client]

[sous-chef1-dev ~]# grep relayhost /etc/postfix/main.cf
relayhost = mailrelay.dev.dorqtown.com

where to look?

Yo,

Thanks for the paste, comments in-line:

On 28 September 2011 07:32, kallen@groknaut.net wrote:

On Tue, 27 Sep 2011, AJ Christensen wrote:

Yo,

Your environments attributes are wrong:

On 27 September 2011 17:49, kallen@groknaut.net wrote:

first, the prod and dev environments:

[chef-repo]$ knife environment show dev
chef_type: environment
cookbook_versions:
default_attributes:
mail-client:
relayhost: mungbeans.dev.dorqtown.com
mail-server:
relayhost: [smtp.gmail.com]:587
description: Development environment (dev)
json_class: Chef::Environment
name: dev
override_attributes:

this should be:
default_attributes "postfix" => { "relayhost" => "whatever" }

The attributes are deep merged together onto the node and thus the
atribute structure must remain the same. Does this make sense?

If you can post the on-disk, ruby version of the environment files I
can point out the problem, otherwise good luck!

i can show you the json version of the env files. i was trying to
cobble together the ruby, but not getting it quickly. for the sake of
speed i'll show the json. i see what you're saying about attribute
structure, so i corrected it, i believe. but the client's relayhost
in main.cf is still picking up the setting from the postfix cookbook
attr setting rather than the dev env setting.

[chef-repo]$ cat environments/dev.json
{
"name": "dev",
"default_attributes": {
"postfix": {
"mail-server": {
"relayhost": "[outbound.mailhop.org],[smtp.gmail.com]:587"
},
"mail-client": {
"relayhost": "mungbeans.dev.dorqtown.com"
}
}
},
"json_class": "Chef::Environment",
"description": "Development environment (dev)",
"chef_type": "environment"
}

This new one is bad too. The structure you want, quote unquote, is:

"default_attributes": {
"postfix": { "relayhost" : "mungbeans.dev.dorqtown.com" }
}

Notice the wildly obvious exclusion of any mention of the "name" of
your other roles, "mail-server" and "mail-client" - the names of the
roles are irrelevant. they are attribute holders - you will unlikely
ever refer to them by name apart from when doing a Search or run_list
introspection for dual-behavior.

This whole pattern you're in - setting things globally - is a sure
sign of a cfengine "expert". In chef, you do not want to be doing
that configuration - you want to be discovering it. The relay server
node can expose attributes to the search index, which is exposed to
all nodes with access. You can simply query for a combination of a
recipe + particular attribute/value.

I'd suggest using the existing Opscode cookbooks which already
implement Search for discovery of the local relay master, by toggling
an attribute.

https://github.com/opscode/cookbooks/blob/master/postfix/attributes/default.rb#L1

e.g.

role postfix_client defaults postfix.client_type = "client"
role postfix_server defaults postfix.client_type = "master"

Done.

–AJ

[chef-repo]$ knife node show sous-chef1.dev.dorqtown.com -r
run_list: role[mail-client]

[sous-chef1-dev ~]# grep relayhost /etc/postfix/main.cf
relayhost = mailrelay.dev.dorqtown.com

where to look?

On Tue, 27 Sep 2011, Matt Ray wrote:

Could you show the output of
knife node show yourmail-server
knife node show yourmail-server -a postfix
knife environment show dev
knife environment show prod

[chef-repo]$ knife node show sous-chef2.dev.dorqtown.com
Node Name: sous-chef2.dev.dorqtown.com
Environment: dev
FQDN: sous-chef2.dev.dorqtown.com
IP: 50.19.69.96
Run List: role[mail-server]
Roles: mail-server
Recipes: postfix
Platform: centos 5.6

[cheftain01]$ knife node show sous-chef2.dev.dorqtown.com -a postfix
postfix:
mail-client:
relayhost: mungbeans.dev.dorqtown.com
mail-server:
relayhost: [outbound.mailhop.org],[smtp.gmail.com]:587
mail_relay_networks: 127.0.0.0/8
mail_type: mail-client
mydomain: dev.dorqtown.com
myhostname: sous-chef2.dev.dorqtown.com
myorigin: $myhostname
relayhost: mailrelay.dev.dorqtown.com
smtp_fallback_relay: [smtp.gmail.com]:587
smtp_sasl_auth_enable: no
smtp_sasl_passwd:
smtp_sasl_password_maps: hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options: noanonymous
smtp_sasl_user_name:
smtp_tls_cafile: /etc/postfix/cacert.pem
smtp_use_tls: no

[chef-repo]$ knife environment show dev
chef_type: environment
cookbook_versions:
default_attributes:
postfix:
mail-client:
relayhost: mungbeans.dev.dorqtown.com
mail-server:
relayhost: [outbound.mailhop.org],[smtp.gmail.com]:587
description: Development environment (dev)
json_class: Chef::Environment
name: dev
override_attributes:

[chef-repo]$ knife environment show prod
chef_type: environment
cookbook_versions:
default_attributes:
mail-client:
relayhost: mailrelay.prod.dorqtown.com
mail-server:
relayhost: [smtp.sendgrid.net]:587
smtp_fallback_relay: [outbound.mailhop.org],[smtp.gmail.com]:587
description: Production environment
json_class: Chef::Environment
name: prod
override_attributes:

Are any of the roles setting the attributes?

nope. the roles only set the run-list.

Here are the precedence
rules for reference:
http://wiki.opscode.com/display/chef/Attributes#Attributes-Precedence

Thanks,
Matt Ray
Senior Technical Evangelist | Opscode Inc.
matt@opscode.com | (512) 731-2218
Twitter, IRC, GitHub: mattray

hai, responses inline.

On Wed, 28 Sep 2011, AJ Christensen wrote:

[chef-repo]$ cat environments/dev.json
{
"name": "dev",
"default_attributes": {
"postfix": {
"mail-server": {
"relayhost": "[outbound.mailhop.org],[smtp.gmail.com]:587"
},
"mail-client": {
"relayhost": "mungbeans.dev.dorqtown.com"
}
}
},
"json_class": "Chef::Environment",
"description": "Development environment (dev)",
"chef_type": "environment"
}

This new one is bad too. The structure you want, quote unquote, is:

"default_attributes": {
"postfix": { "relayhost" : "mungbeans.dev.dorqtown.com" }
}

Notice the wildly obvious exclusion of any mention of the "name" of
your other roles, "mail-server" and "mail-client" - the names of the
roles are irrelevant. they are attribute holders - you will unlikely
ever refer to them by name apart from when doing a Search or run_list
introspection for dual-behavior.

ah.. and now that i've corrected the dev env with your feedback
above, it's working, in that a client's main.cf gets the env relayhost
rather that the default one from the cookbook. yay!

This whole pattern you're in - setting things globally - is a sure
sign of a cfengine "expert".

ayep. i'm workin' on grokkin' a new config mgmt paradigm here.

In chef, you do not want to be doing
that configuration - you want to be discovering it. The relay server
node can expose attributes to the search index, which is exposed to
all nodes with access. You can simply query for a combination of a
recipe + particular attribute/value.

I'd suggest using the existing Opscode cookbooks which already
implement Search for discovery of the local relay master, by toggling
an attribute.

https://github.com/opscode/cookbooks/blob/master/postfix/attributes/default.rb#L1

e.g.

role postfix_client defaults postfix.client_type = "client"
role postfix_server defaults postfix.client_type = "master"

i just ran thru the opscode postfix cookbook from a pristine state,
and followed jtimberman's blog about "Encrypted Data Bag for Postfix
SASL Authentication". that helped turn a little light on for me, even
tho i'm getting a chef client error about smtp_sasl (i'll poke at that
later). so i skip the smtp_sasl bit, and just try to get a vanilla
postfix master and client.

my postfix master node kept converging as a client until, while using
jtimberman's "operations master" role, i added an override_attribute
to that role as "mail_type" => "master". once i did that, it worked:
it became a master. (jtimberman, is that missing from your role in this
blog post?)

now i wonder if i'm still falling back into setting things globally.
am i? is there a better, more flexible way to do this?

my mail-server role, based on jtimberman's post
(http://jtimberman.posterous.com/64227128), sans recipe[postfix::sasl_auth]:

name "mail-server"
override_attributes(
"postfix" => {
"mail_type" => "master",
"relayhost" => "[outbound.mailhop.org]",
"smtp_sasl_auth_enable" => "no",
"smtp_sasl_passwd" => "",
"smtp_sasl_user_name" => ""
}
)

practice practice practice.. thanks for your help so far.

kallen

Yo,

On 28 September 2011 14:32, kallen@groknaut.net wrote:

hai, responses inline.

On Wed, 28 Sep 2011, AJ Christensen wrote:

[chef-repo]$ cat environments/dev.json
{
"name": "dev",
"default_attributes": {
"postfix": {
"mail-server": {
"relayhost": "[outbound.mailhop.org],[smtp.gmail.com]:587"
},
"mail-client": {
"relayhost": "mungbeans.dev.dorqtown.com"
}
}
},
"json_class": "Chef::Environment",
"description": "Development environment (dev)",
"chef_type": "environment"
}

This new one is bad too. The structure you want, quote unquote, is:

"default_attributes": {
"postfix": { "relayhost" : "mungbeans.dev.dorqtown.com" }
}

Notice the wildly obvious exclusion of any mention of the "name" of
your other roles, "mail-server" and "mail-client" - the names of the
roles are irrelevant. they are attribute holders - you will unlikely
ever refer to them by name apart from when doing a Search or run_list
introspection for dual-behavior.

ah.. and now that i've corrected the dev env with your feedback
above, it's working, in that a client's main.cf gets the env relayhost
rather that the default one from the cookbook. yay!

This whole pattern you're in - setting things globally - is a sure
sign of a cfengine "expert".

ayep. i'm workin' on grokkin' a new config mgmt paradigm here.

In chef, you do not want to be doing
that configuration - you want to be discovering it. The relay server
node can expose attributes to the search index, which is exposed to
all nodes with access. You can simply query for a combination of a
recipe + particular attribute/value.

I'd suggest using the existing Opscode cookbooks which already
implement Search for discovery of the local relay master, by toggling
an attribute.

https://github.com/opscode/cookbooks/blob/master/postfix/attributes/default.rb#L1

e.g.

role postfix_client defaults postfix.client_type = "client"
role postfix_server defaults postfix.client_type = "master"

i just ran thru the opscode postfix cookbook from a pristine state,
and followed jtimberman's blog about "Encrypted Data Bag for Postfix
SASL Authentication". that helped turn a little light on for me, even
tho i'm getting a chef client error about smtp_sasl (i'll poke at that
later). so i skip the smtp_sasl bit, and just try to get a vanilla
postfix master and client.

my postfix master node kept converging as a client until, while using
jtimberman's "operations master" role, i added an override_attribute
to that role as "mail_type" => "master". once i did that, it worked:
it became a master. (jtimberman, is that missing from your role in this
blog post?)

Sounds like a bug in the blog post, for sure.

now i wonder if i'm still falling back into setting things globally.
am i? is there a better, more flexible way to do this?

I'd advise, for a beginner attempting to concrete some ideology, a
postfix_master role that defaults the attribute postfix.mail_type to
"master".

You can easily include this role in another role to turn it into a
postfix master, instead of cluttering up your "mail-server" role which
theoretically could be extended to support multiple portions of the
Postfix system; maybe a spam filter, rewriter server or handling final
delivery.

It also keeps all postfix master related settings in a single file /
attribute setting for ease of management.

You can also use the environmental run lists functionality of
environments to say, consolidate the postfix-master role automatically
onto any mail-server role in the development environment (or similar).

my mail-server role, based on jtimberman's post
(http://jtimberman.posterous.com/64227128), sans recipe[postfix::sasl_auth]:

postfix-master.rb:

name "postfix-master"
default_attributes(
"postfix" => {
"mail_type" => "master",
"relayhost" => "[outbound.mailhop.org]"
}
)

mail-server.rb:
name "mail-server"
default_attributes(
"postfix" => {
"smtp_sasl_auth_enable" => "no",
"smtp_sasl_passwd" => "",
"smtp_sasl_user_name" => ""
}
)

I hope this helps.

–AJ