Skip to content

Instantly share code, notes, and snippets.

@maxivak
Last active February 19, 2021 19:30
Show Gist options
  • Save maxivak/75eabc7ff292dd86c07ddc95add75953 to your computer and use it in GitHub Desktop.
Save maxivak/75eabc7ff292dd86c07ddc95add75953 to your computer and use it in GitHub Desktop.
Provisioning Remote server accessible by SSH with Chef and knife-zero

Provisioning remote server accessible by SSH with Chef and knife-zero.

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

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.

Setup workstation

  • 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
]

Prepare node

  • 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

Provision

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]"

Provision with cookbooks

  • 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"
}

Provision with roles

  • 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 server

  • run command on the remote node
knife ssh "name:mynode1" --ssh-user vagrant command_here

References

@bbl
Copy link

bbl commented Feb 7, 2017

Great! Thx!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment