I have a recipe for provisioning an ec2 instance that I'm trying to apply an environment to, which I run as:
chef-client -z -o 'myapp::dev_create'
The default.rb attributes file is defined as:
default['myapp_provisioner'].tap do |myapp_provisioner|
myapp_provisioner['node_name'] = 'test'
end
The myapp::dev_create recipe is defined as:
require 'chef/provisioning'
Chef::Config.chef_provisioning({
:machine_max_wait_time => 240
})
# Override environment specific configs
node.override['myapp_provisioner']['node_name'] = 'RULZ_DEV'
include_recipe 'myapp_provisioner::ec2_instance' # sets machine_options
# The line below prints "RULZ_DEV"
# as it is overridden above
puts node['myapp_provisioner']['node_name']
machine node['myapp_provisioner']['node_name'] do
chef_environment 'DEV'
admin true # run as sudo
recipe 'myapp::copy_tls_certs'
role 'reverse_proxy'
role 'app_server'
end
The Recipe myapp::copy_tls_certs is defined as:
node_name = node['myapp_provisioner']['node_name']
# The line below prints the value from default attributes "test"
puts "cert path ---------------> #{node_name}"
Updated
I had previously titled the question as Chef Environment not overriding recipe called inside a machine resource
, but I have come to realize that the issue is not related to Environments, but is only about attributes overriding and using those attributes inside a machine resource. It feels like I'm missing something quite fundamental here, any ideas?
The answer is simple. Your EC2 machine has no idea about
node['myapp_provisioner']['node_name']
being overridden inmyapp::dev_create
recipe, because this recipe is not in its run list.What chef-client does on that machine is:
Expand the run list.
It gets the
myapp::copy_tls_certs
recipe and those others that make thereverse_proxy
andapp_server
roles. (but they are not important now)It reads all the attribute files of the cookbooks in the expanded run list.
So it reads
myapp/attributes/default.rb
and gets the default value for thenode['myapp_provisioner']['node_name'] = 'test'
It goes through the recipes in run list and creates a collection of resources or executes ruby code, if it's not a resource.
In your case it runs
myapp::copy_tls_certs
and prints thetest
, because that's what it is :)If you want your overridden attribute to be in the provisioned EC2 machine, you have to move the override line to some other recipe, which you can then include into
machine
resourcerecipe
attribute. Or may be (I don't know, because I have never seen thismachine
resource before) thismachine
resource has alsoattribute
property, so you can pass the override attribute through it.