I'm new to Chef and have been using Test Kitchen to test the validity of my cookbooks, which works great. Now I'm trying to ensure that environment-specific attributes are correct on production nodes prior to running Chef initially. These would be defined in a role.
For example, I may have recipes that converge using a Vagrant box with dev settings, which validates the cookbook. I want to be able to test that a production node's role. I think I want these tests as the source of truth describing my environment. Looking at Test Kitchen's documentation, this seems beyond its scope.
Is my assumption correct? Is there a better approach to test a cookbook before the first time Chef is run on a production node to ensure it has the correct settings?
Chefs are culinary professionals trained in all aspects of food preparation. Their main responsibilities include planning menus, overseeing the kitchen staff, and ensuring that the food meets high-quality standards.
Setting Environment Variable Using Chef RecipeStep 1 − Update the default recipe of cookbook with an environment variable. Step 2 − Upload the updated cookbook to the server. Step 3 − Running the Chef client to create a temp file.
You need to upload your role on your Chef server by using the knife role from file command. Only then should you add the role to your node's run list. Running the Chef client on a node having your role in its run list will execute all the recipes listed in the role.
I pleasantly discovered that chef_zero uses the "test/integration" directory as it's chef repository.
Just create your roles under
Standard Chef cookbook layout.
├── attributes
│ └── default.rb
├── Berksfile
├── Berksfile.lock
├── chefignore
├── .kitchen.yml
├── metadata.rb
├── README.md
├── recipes
│ └── default.rb
└── test
└── integration
├── default
│ └── serverspec
│ ├── default_spec.rb
│ └── spec_helper.rb
└── roles
└── demo.json
---
driver:
name: vagrant
provisioner:
name: chef_zero
platforms:
- name: ubuntu-14.04
suites:
- name: default
run_list:
- role[demo]
attributes:
Notes:
file "/opt/helloworld.txt" do
content "#{node['demo']['greeting']}"
end
default['demo']['greeting'] = "hello world"
Notes:
require 'spec_helper'
describe file('/opt/helloworld.txt') do
it { should be_file }
its(:content) { should match /this came from my role/ }
end
Notes:
{
"name": "demo",
"default_attributes": {
"demo": {
"greeting": "this came from my role"
}
},
"run_list": [
"recipe[demo]"
]
}
You can set both roles and environments in your .kitchen.yml, so you certainly can test this with test kitchen.
....
provisioner:
roles_path: path/to/your/role/files
client_rb:
environment: your_environment
.....
That said, I personally prefer to use role cookbooks. If you have a fixed set of environments, as we do, then you can also use simple conditionals in the attributes files of your role cookbook to adjust attributes based on environment too. That way, you have a single cookbook that defines the entire configuration of your node by wrapping other cookbooks and setting variables. With that setup, it is very easy to setup kitchen tests that validate the exact production system.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With