RFC | Title | Authors | Status | Type |
---|---|---|---|---|
71 |
Knife Bootstrap client Configuration |
Jay Mundrawala <[email protected]>, Bryan McLellan <[email protected]> |
Accepted |
Standards Track |
Knife bootstrap currently only allows a select few client.rb
parameters
to be specified during bootstrap. This RFC proposes a solution to allow users
to pass bulk configuration data to knife bootstrap
to be placed in the
client.rb
before the first chef-client run.
The knife bootstrap
command supports a small subset of possible parameters
a user can configure in the client.rb
. The chef-client cookbook provides a
template that supports many more, allowing the user to configure additional
options during a Chef client converge. If something you are trying to do does
not fit into the template provided, you are also free to specify config files
in a client.d
folder that will automatically be loaded. However, because
the chef-client cookbook is run along with the rest of the run list on the
first run, your settings do not take effect until the second chef-client
run.
As a Chef user,
I want to be able to configure chef-client with options that aren't supported by knife bootstrap,
so that I do not have to maintain a fork of the bootstrap template,
or so that I do not have to learn about bootstrap templates at all,
or so that I don't have to make two chef-client runs on bootstrap to apply and use my configuration file.
As a Chef developer,
I want the user to have a generic way to pass custom client configuration file,
so that I don't have the maintenance cost of additional bootstrap arguments for new features
The chef-client
cookbook adds a block to load all .rb
files in
the client.d
folder. The proposal here is to do the same thing.
Knife bootstrap will take a client.d
folder, by default looking
the chef repo under bootstrap
, optionally overwritable with a
knife.rb
configuration parameter client_d_path
. The files
will be loaded in alphabetical order. Knife will still sync all files
under client.d
, however only top-level files will the automatically
loaded. The block to do this would look something like:
Dir.glob("/etc/chef/client.d/*.rb").sort.each do |conf|
Chef::Config.from_file(conf)
end
For this example, consider we want to configure Ohai's hostname plugin. The execution of this plugin will determine the node name that will be assigned to the node we are bootstraping, so it needs to be correct on the first run.
We store the ohai_config.rb
file in the Chef repo on our workstation:
# chef-repo/bootstrap/client.d/ohai_config.rb
ohai.plugin[:hostname][:fqdn_using] = [ :hostname, :nis, :dns ]
# chef-repo/bootstrap/client.d/ohai_plugins/custom_plugin.rb
# My custom ohai plugin
Next we bootstrap the node:
knife bootstrap 10.0.0.100 -x chefuser -P oneofus
This generates the following client.rb
and copies it to the box,
along with all the contents in our chef repo's client.d
directory:
# /etc/chef/client.rb
log_level :info
log_location STDOUT
chef_server_url "https://api.chef.io/organizations/oneofus"
ohai.plugin_path = "/etc/chef/client.d/ohai_plugins"
Dir.glob("/etc/chef/client.d/*.rb").sort.each do |conf|
Chef::Config.from_file(conf)
end
# /etc/chef/client.d/ohai_config.rb
ohai.plugin[:hostname][:fqdn_using] = [ :hostname, :nis, :dns ]
# /etc/chef/client.d/ohai_plugins/custom_plugin.rb
# My custom ohai plugin
Now, when chef-client runs on the box, our configurations to Ohai's hostname plugin will be loaded before Ohai runs, allowing the first Chef run to get the correct hostname.
Taking a look under /etc/chef
, we should see something like:
[vagrant@localhost ~]$ tree /etc/chef/
/etc/chef/
├── client.d
│ ├── ohai_config.rb
│ └── ohai_plugins
│ └── custom_plugin.rb
├── client.pem
├── client.rb
├── first-boot.json
├── trusted_certs
│ └── localhost.crt
└── validation.pem
This work is in the public domain. In jurisdictions that do not allow for this, this work is available under CC0. To the extent possible under law, the person who associated CC0 with this work has waived all copyright and related or neighboring rights to this work.