Mahlatse Makalancheche
Mahlatse Makalancheche

Reputation: 441

Chef - using overriden attributes inside recipes applied inside a machine resource

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?

Upvotes: 1

Views: 612

Answers (2)

Mahlatse Makalancheche
Mahlatse Makalancheche

Reputation: 441

For the next person that will go through a similar problem, this is what I ended up with.

The myapp::create recipe is defined as:

require 'chef/provisioning'

# Override attributes [I put these in an Environment file, much cleaner]
node.override['myapp_provisioner']['node_name'] = 'RULZ_DEV'

include_recipe 'myapp_provisioner::ec2_instance' # sets machine_options 

machine node['myapp_provisioner']['node_name'] do
  chef_environment 'DEV'
  admin true # run as sudo
  attributes node['myapp_provisioner'] # pulls all attributes
  role 'reverse_proxy'
  role 'app_server'
end

That pulls overriding attributes into newly created normal attributes during the chef-client run. As indicated in the comment, I put these in an environment file to keep the recipe clean and I run that as:

chef-client -z -o 'brms::reate' -E DEV

Upvotes: 0

Draco Ater
Draco Ater

Reputation: 21226

The answer is simple. Your EC2 machine has no idea about node['myapp_provisioner']['node_name'] being overridden in myapp::dev_create recipe, because this recipe is not in its run list.

What chef-client does on that machine is:

  1. Expand the run list.

    It gets the myapp::copy_tls_certs recipe and those others that make the reverse_proxy and app_server roles. (but they are not important now)

  2. 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 the node['myapp_provisioner']['node_name'] = 'test'

  3. 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 the test, 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 resource recipe attribute. Or may be (I don't know, because I have never seen this machine resource before) this machine resource has also attribute property, so you can pass the override attribute through it.

Upvotes: 1

Related Questions