We have a server(node) accessible by SSH. We want to provision using Chef recipes stored on our local chef repo.
We will use gem knife-zero
.
Find an example of Chef repo here.
Knife-Zero is not a replacement of Knife-Solo. Knife-Zero adds the function which can do a target remotely to the local_mode which is a subset of the Chef-Server/Client environment.
Knife-zero - runs chef-client at remote node with chef-zero server (local-mode) via HTTP over SSH port forwarding.
- install knife-zero
chef gem install knife-zero
- create knife.rb in local chef repo
cd chef-repo
touch .chef/knife.rb
file .chef/knife.rb
:
local_mode true
current_dir = File.dirname(__FILE__)
# path to cookbooks or repo
cookbook_path [
File.expand_path('../../berks-cookbooks', __FILE__),
"site-cookbooks",
]
#chef_repo_path File.expand_path('../' , __FILE__)
#
knife[:ssh_attribute] = "knife_zero.host"
# if you need sudo to run recipes
knife[:use_sudo] = true
## use specific key file to connect server instead of ssh_agent(use ssh_agent is set true by default).
# knife[:identity_file] = "~/.ssh/id_rsa"
#
ssl_verify_mode :verify_none
# berkshelf
#knife[:before_bootstrap] = "berks vendor"
#knife[:before_converge] = "berks vendor"
knife[:before_bootstrap] = "chef exec berks vendor"
knife[:before_converge] = "chef exec berks vendor"
## Attributes of node objects will be saved to json file.
## the automatic_attribute_whitelist option limits the attributes to be saved.
knife[:automatic_attribute_whitelist] = %w[
fqdn
os
os_version
hostname
ipaddress
roles
recipes
ipaddress
platform
platform_version
platform_version
cloud
cloud_v2
chef_packages
]
- bootstrap node - install chef tools on the server
knife zero bootstrap 11.22.33.44 --ssh-user ubuntu --ssh-password mypass --node-name mynode1
read more about options for knife zero bootstrap
: http://knife-zero.github.io/30_subcommands/
- check node info
knife node show mynode1
use command knife zero converge
to run chef-client on the remote node
- basic usage:
knife zero converge "name:mynode1" --ssh-user vagrant
- run recipe
chef exec knife zero converge "name:mynode1" --ssh-user root --ssh-password root --ssh-port 22 --attribute knife_zero.host --override-runlist recipe_name
- run with extra attributes in json file
knife zero converge "name:mynode1" --ssh-user root --ssh-password root --attribute knife_zero.host --json-attributes myvars.json --override-runlist "recipe1,role[role1]"
- create cookbook
add your cookbooks to site-coobooks folder
cd site-cookbooks
chef generate cookbook example1
this will create cookbook in folder 'cookbooks/example1'
- edit recipe 'cookbooks/example1/recipes/default.rb'
file '/tmp/my.txt' do
content "hello"
end
- add external cookbook using Berkshelf
add to file Berksfile
source 'https://supermarket.chef.io'
#source "https://api.berkshelf.com"
...
cookbook 'chef-cookbook-example-1', github: 'maxivak/chef-cookbook-example-1'
- install cookbook
chef exec berks install
it will copy new cookbooks to berks-cookbooks folder. Now you can use recipes from this cookbook in run_list.
- Provision with recipe
knife zero converge "name:mynode1" --ssh-user vagrant --override-runlist example1
# or
knife zero converge "name:mynode1" --ssh-user vagrant --override-runlist 'recipe[example1]'
- provision with recipe and custom attributes
knife zero converge "name:mynode1" --ssh-user vagrant --json-attributes myvars.json --override-runlist example1
where myvars.json:
{
"mytest": "v1",
"attr2": "2"
}
- create Chef role where node attributes and list of recipes to run are specified
file 'roles/myrole.json'
{
"name": "myrole",
"description": "my sample role",
"json_class": "Chef::Role",
"default_attributes": {
"var1": "some-value-1"
},
"run_list": [
"recipe[example1]",
"recipe[anothercookbook::recipename]"
]
}
- recipe
cookbooks/example1/recipes/default.rb
use attribute valuu in recipe
file '/tmp/my.txt' do
content node[:var1]
end
- run provision
knife zero converge "name:mynode1" --ssh-user root --attribute knife_zero.host --override-runlist "role[myrole]"
- check file on server
cat /tmp/my.txt
# it should contain
some-value-1
- run provision with role and attributes
knife zero converge "name:mynode1" --ssh-user root --attribute knife_zero.host --override-runlist "role[myrole]"
- attributes file
myvars.json
{
"var1": "new-value",
"var2": {
...
}
}
- check file
cat /tmp/my.txt
# it should contain
new-value
- run command on the remote node
knife ssh "name:mynode1" --ssh-user vagrant command_here
- Example of Chef repo - https://github.com/maxivak/chef-repo-template.
Great! Thx!!