A practical approach to chef (Using Vagrant)
Composed by Haggai Philip Zagury / @hagzag
Guy Ben-Porat, Development Manager “ExLibris”
http://prezi.com/8zwcr5df9eno/chef-intro-chef-server-workflow
Lets go through this prezi together
We know what !
Chef is - and what it solves Chef server / solo / knife (WS)are
Let's write a simple cookbook ...
*git bash is also used in order to ssh into a vagrant image on windows
Write a cookbook
Omnibus installer will "figure out" your OS and install it In addition to an embedded version of chef
On *nix / MacOSX
curl -L https://www.opscode.com/chef/install.sh | sudo bash /opt/opscode/...
On Windows [Download link]
https://opscode-omnibus-packages.s3.amazonaws.com/windows/2008r2/x86_64/chef-client-11.8.0-1.windows.msi c:\opscode
We don't really need knife (at this stage), so we will just provide it with the defaults
Execute & Accept all defaults:
knife configure WARNING: No knife configuration file found Where should I put the config file? [/home/hagzag/.chef/knife.rb] y Please enter the chef server URL: [https://<hostname>:443] Please enter an existing username or clientname for the API: [hagzag] Please enter the validation clientname: [chef-validator] Please enter the location of the validation key: [/etc/chef-server/chef-validator.pem] ... ***** Configuration file written to /home/hagzag/.chef/knife.rb </hostname>
knife cookbook create ntp -o .
We get:
attributes/ definitions/ files/ libraries/ metadata.rb providers/ README.rdoc recipes/ resources/ templates/
Shortcut => Get from git:
git clone git@github.com:tikalk-cookbooks/ntp-intro.git git checkout -b 0.1.0
vim cookbooks/ntp/recipes/default.rb
package "ntp" do action [:install] end
yum install ntp
template "/etc/ntp.conf" do source "ntp.conf.erb" variables( :ntp_server => "time.nist.gov" ) notifies :restart, "service[ntpd]" end
vim cookbooks/ntp/templates/default/ntp.conf.erb
restrict default kod nomodify notrap nopeer noquery restrict -6 default kod nomodify notrap nopeer noquery restrict 127.0.0.1 restrict -6 ::1 server <%= @ntp_server %> server 127.127.1.0 # local clock driftfile /var/lib/ntp/drift keys /etc/ntp/keys
https://raw.github.com/tikalk-cookbooks/ntp-intro/0.1.0/templates/default/ntp.conf.erb
Similar to manually editing the /etc/ntp.conf
service "ntpd" do action [:enable,:start] end
chkconfig ntp on
What have we here ?
Install ntp Configure the service via template file Enable and start the serviceIf yours differs - compare with:https://github.com/tikalk-cookbooks/ntp-introuse tag 0.1.0
Sharpen your knives => Improve the cookbook
vim ntp/attributes/default.rb
Use a case statement to differentiate between platforms
case x when 1,2,3 puts "1, 2, or 3" when 10 puts "10" else puts "Some other number" endRubydoc case statement
case platform when "redhat","centos","fedora","scientific" default[:ntp][:service] = "ntpd" when "ubuntu","debian" default[:ntp][:service] = "ntp" else default[:ntp][:service] = "ntpd" end
In order to support more than 1 server In this example add:
0.pool.ntp.org, 1.pool.ntp.org, 2.pool.ntp.org, 3.pool.ntp.org
We have 4 servers in out attributes file (but we might have 5 tomorrow ...)
0.pool.ntp.org, 1.pool.ntp.org, 2.pool.ntp.org, 3.pool.ntp.org
Our template file will is an erb file + loop over the servers array using the .each method
default[:ntp][:servers] = ["0.pool.ntp.org", "1.pool.ntp.org", "2.pool.ntp.org", "3.pool.ntp.org"]
# Generated by Chef for <%= node[:fqdn] %> # node[:fqdn] = ohai data collected on node ! # Local modifications will be overwritten. restrict -6 ::1 #server <%= @ntp_server %> <% node[:ntp][:servers].each do |ntpsrv| -%> server <%= ntpsrv %> iburst restrict <%= ntpsrv %> nomodify notrap noquery <% end -%>
# Generated by Chef for <%= node[:fqdn] %> # node[:fqdn] = ohai data collected on node ! # Local modifications will be overwritten.
Re-arrange recipe
package "ntp" do action [:install] end
The package name is similar on all platforms so there is no real change here ...
[3of3] on github tag 0.1.1
service node[:ntp][:service] do service_name node[:ntp][:service] action [:enable,:start,:restart] end
Service declaration - the service name and it's implied location /etc/init.d/ntp or /etc/init.d/ntpd
based on: service =>node[:ntp][:service]template "/etc/ntp.conf" do source "ntp.conf.erb" owner "root" group "root" mode 0644 notifies :restart, resources(:service => node[:ntp][:service]) end
This part is also the same as before just with a shift in it's location
package "ntp" do action [:install] end service node[:ntp][:service] do service_name node[:ntp][:service] action [:enable,:start,:restart] end template "/etc/ntp.conf" do source "ntp.conf.erb" owner "root" group "root" mode 0644 notifies :restart, resources(:service => node[:ntp][:service]) end
What have we here ?
Install ntp on ubutnu + centos Configure the service via template file Support 1...n ntp servers Enable and start the serviceIf yours differs - compare with:https://github.com/tikalk-cookbooks/ntp-introuse tag 0.1.1
We want to test this cookbook & we need a server to test this on right ? A good place to introduce
Use opscode's @ https://github.com/opscode-cookbooks/ntp
This one is just for play ;)
Off-line copy is available with workshop materials
cd ~/My_Cool_Project vagrant init My_Cool_Project http://shonky.info/centos64.box
So now you have a skeleton [ with good remarks ] of a Vagrantfile
Define a box & box url
config.vm.box = "CentOS 6.4 x86_64" config.vm.box_url = "http://bit.ly/1aNaifu"
config.vm.network "private_network", ip: "192.168.56.80"
config.vm.network "public_network # will get DHCP from your LAN
NAME = "MyAwesomeVM"
config.vm.hostname = "#{NAME}"
Define your provisioner: shell/chef/puppet
shell example:
config.vm.provision :shell, :path => File.expand_path("../bootstrap.sh", __FILE__)
config.vm.provision :chef_solo do |chef| chef.cookbooks_path = ["cookbooks", "site-cookbooks"] chef.roles_path = ["roles"] chef.log_level = ENV['CHEF_LOG'] ? ENV['CHEF_LOG'].to_sym : :info chef.add_role "web" # chef.add_recipe "nginx" => marked out but you can also add recipes ... end
More about provisioner(s) here
Define your provider: virtualbox, aws, vmware fusion
Customize you virtualbox machine:
config.vm.provider :virtualbox do |vb| # Don't boot with headless mode # vb.gui = true vb.customize [ "modifyvm", :id, "--memory", "512"] vb.name = "#{NAME}" end
Add some "juice" to your machine [if you need it]
More about providers here
First try virtual box unless --provider is specifiedif --provider=aws ignore all vb customizations (or networking for that matter)
Look for a provisioner Chef / Shell / Salt / Other ..., more then one great !
config.vm.provision "shell", inline: "[[ `which chef-solo` ]] || curl -L https://www.opscode.com/chef/install.sh | sudo bash" config.vm.provision :chef_solo do |chef| chef.cookbooks_path = ["cookbooks", "site-cookbooks"] chef.roles_path = ["roles"] chef.log_level = ENV['CHEF_LOG'] ? ENV['CHEF_LOG'].to_sym : :info chef.add_role "web" end
Work in the cloud - AWS example:
config.vm.provider :aws do |aws, override| # Add aws tags aws.tags = { 'vagrant' => 'true', 'environment' => 'devenv' } aws.access_key_id = ENV['AWS_ACCESS_KEY'] aws.secret_access_key = ENV['AWS_SECRET_KEY'] aws.keypair_name = "A_VAGRANT_KEYPAIR" aws.security_groups = [ "MySecurotyGroupWithSSHOpen" ] aws.region = "us-west-2" aws.ami = "ami-myami" endIn the example above set the AWS_ACCESS_KEY & AWS_SECRET_KEY and execute
vagrant up --provider=aws
For example:
AWS (Amazon Web Services) plugin librarian-chef plugin Berkshelf pluginEasy as:
vagrant plugin install [plugin-name]
Use installer suitable for your platform from: Virtualbox site Offline copy is available with workshop materials
Offline copy is available with workshop materials
No extra configuration needed (at this point ...)
cd path/to/project vagrant init
You should get a clean vagrant file
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "CentOS 6.5 x86_64" config.vm.box_url = "http://bit.ly/1aNaifu"
In order to save time I have provided an offline copy of this box: Add it by excuting the command Vagrant box add like so:
vagrant box add "CentOS 6.5 x86_64" file:///path/to/vbox/image-bundle.box
This command will add to your home folder ~/.vagrnat/boxes/CentOS 6.5 x86_64
vagrant box add "centos65-x86_65" /Volumes/TOSHIBADISK/Vagrant-Boxes/centos65-x86_64-20131205.box Downloading box from URL: file:/Volumes/TOSHIBADISK/Vagrant-Boxes/centos65-x86_64-20131205.box Extracting box...te: 245M/s, Estimated time remaining: --:--:--) Successfully added box 'centos65-x86_65' with provider 'virtualbox'!
cd path/to/project vagrant up Bringing machine 'default' up with 'virtualbox' provider... [default] Importing base box 'CentOS 6.5 x86_64'... [default] Matching MAC address for NAT networking... [default] Setting the name of the VM... [default] Clearing any previously set forwarded ports... [default] Clearing any previously set network interfaces... [default] Preparing network interfaces based on configuration... [default] Forwarding ports... [default] -- 22 => 2222 (adapter 1) [default] Booting VM... [default] Waiting for machine to boot. This may take a few minutes... DL is deprecated, please use Fiddle [default] Machine booted and ready! [default] Mounting shared folders... [default] -- /vagrant
Open Virtual box Manager ans see you have a box there, Then desory it ...
vagrant destroy -f
-f used for force ...
config.vm.provider "virtualbox" do |vb| vb.gui = true vb.customize ["modifyvm", :id, "--memory", 512] vb.customize ["modifyvm", :id, "--ioapic", "on", "--cpus", 1] end
Note the vb.gui = true option here, in this case I would like the Virtualbox GUI to startup !
Is now
We cloud choose a vagran box with chef client installed ..., but where is the fun in that ?
config.vm.provision "shell", inline: "[[ `which chef-solo` ]] || curl -L https://www.opscode.com/chef/install.sh | sudo bash"
Use chef to install our ntp cookbook from ex02
config.vm.provision :chef_solo do |chef| chef.cookbooks_path = ["cookbooks" ] chef.add_recipe "ntp" end
Copy the ntp cookbook in to a directory called cookbooks
mkdir ./cookbooks cp -R ntp cookbooks
Execute the vagrant provision
$ vagrant provision [default] Running provisioner: shell... [default] Running: inline script [default] Running provisioner: chef_solo... Generating chef JSON and uploading...
Vagrant is trigerring chef-solo ...
Running chef-solo... [] INFO: Forking chef instance to converge... [] INFO: *** Chef 11.10.0 *** [] INFO: Chef-client pid: 1655 [] INFO: Setting the run_list to ["recipe[ntp]"] from JSON [] INFO: Run List is [recipe[ntp]] [] INFO: Run List expands to [ntp] [] INFO: Starting Chef Run for vagrant-centos65 [] INFO: Running start handlers [] INFO: Start handlers complete.
end of "compliation - begining of converge (execution)"
[] INFO: package[ntp] installing ntp-4.2.6p5-1.el6.centos from base repository [] INFO: service[ntpd] enabled [] INFO: service[ntpd] started [] INFO: service[ntpd] restarted [] INFO: template[/etc/ntp.conf] backed up to /var/chef/backup/etc/ntp.conf.chef-20130913144203.354529 [] INFO: template[/etc/ntp.conf] updated file contents/etc/ntp.conf [] INFO: template[/etc/ntp.conf] sending restart actionto service[ntpd] (delayed) [] INFO: service[ntpd] restarted [] INFO: Chef Run complete in 87.127895456 seconds [] INFO: Running report handlers [] INFO: Report handlers complete
Connect to the machine
vagrant ssh
Is the rpm installed ?
rpm -qa | grep ntp [vagrant@vagrant-centos65 ~]$ rpm -qa | grep ntp ntpdate-4.2.6p5-1.el6.centos.x86_64 ntp-4.2.6p5-1.el6.centos.x86_64
Examine /etc/ntp.conf
[vagrant@vagrant-centos65 ~]$ cat /etc/ntp.conf # Generated by Chef for # node[:fqdn] = ohai data collected on node ! # Local modifications will be overwritten. restrict -6 ::1 #server server 0.pool.ntp.org iburst restrict 0.pool.ntp.org nomodify notrap noquery server 1.pool.ntp.org iburst restrict 1.pool.ntp.org nomodify notrap noquery server 2.pool.ntp.org iburst restrict 2.pool.ntp.org nomodify notrap noquery server 3.pool.ntp.org iburst restrict 3.pool.ntp.org nomodify notrap noquery restrict default kod nomodify notrap nopeer noquery restrict -6 default kod nomodify notrap nopeer noquery restrict 127.0.0.1 server 127.127.1.0 # local clock driftfile /var/lib/ntp/drift keys /etc/ntp/keys
Planned for next session
Chef solo / Chef server ? Manageing dependeices Setup & Use chef server Setup Chef Workstation Use Chef soloIf you followed so far you should already have it all ...
Chef (ruby)knife cookbook create web
vim web/metadata.rb
depends 'nginx'
We will learn later on how this line makes a difference ...
default['nginx']['port'] = '4000' default['nginx']['listen_ports'] = %w[80, #{node['nginx']['port']}] default['nginx']['vhost']['basedir'] = '/var/www/nginx' default['nginx']['vhost']['demo'] = "#{node['nginx']['vhost']['basedir']}/demo"
use an attribute, for the directory name !
include_recipe "nginx" #Create the runtime directory - using directory resource [ chef core resource provider ] directory node[:nginx][:vhost][:demo] do owner 'nginx' group 'nginx' recursive true end
Use a template file ...
template "/etc/nginx/sites-available/demo-site" do # the "default" sites-available dir under nginx's run folder source "demo-site.erb" # the template file to use owner "root" # Owner of the file group "root" # Group of the file mode 0644 # Mode notifies :restart, "service[nginx]" # Restart nginx upon configuration end
Use a template file ...
# nginx virtual host template configured by chef on <%= node[:fqdn] %> server { listen <%= node[:nginx][:port] %> default; server_name <%= node[:fqdn] %>; root <%= node[:nginx][:vhost][:demo] %>; }Will evaluate to:
# nginx virtual host template configured by chef on chef-solo-demo server { listen 4000 default; server_name chef-solo-demo; root /var/www/nginx/demo; }
Use a template file ... Name the file index.html Place it in the document root folder Place an image from http://www.tikalk.com/files/devops-icons1.png in that index.html file
# Create a website from template ... template "#{node[:nginx][:vhost][:demo]}/index.html" do #index file location source "index.html.erb" # now user owner "nginx" # is nginx [ the user running the nginx server !] group "nginx" end
<html> <head></head> <body> <center> <h1>Demo site running on nginx <%= node[:fqdn] %></h1> <div> <img src="http://www.tikalk.com/files/devops-icons1.png" alt="DevOpsIcon"/> </div> <h1>And your'e a full stack developer !!!</h1> </center> </body> </html>
nginx_site "demo-site" do # "nginx_ensite" see :: https://github.com/perusio/nginx_ensite enable :true notifies :restart, "service[nginx]" end # disable iptables ! => just for this demo :) include_recipe "iptables::disabled"
name 'web' maintainer 'Tikal Knowledge LTD' maintainer_email 'c5191707@tikalk.com' license 'Apache 2.0' description 'Installs/Configures web' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) version '0.1.0' depends 'nginx' depends 'iptables' # opend nginx port(S)Make sure you name your cookbook - if not the name will default to the directory name [ not so good ] Make sure the name isn't taken or it will "clash" with community cookbooks !
depends 'nginx' depends 'iptables' # opend nginx port(S)
And know how to get these cookbooks - right ?
echo "cookbook 'nginx'" >> /path/to/Cheffile
Or
echo "cookbook 'nginx'" >> /path/to/Berksfile
Usually will find Berkshelf with a chef server environment and librarian with chef-solo
gem install berkshelf
Define your dependencies
site :opscode cookbook 'mysql' cookbook 'nginx', '~> 0.101.5' cookbook 'web', path: '~/cookbooks/web' cookbook 'lvm', git: 'git://github.com/opscode-cookbooks/lvm.git'
gem install librarian-chef
Define your dependencies
site "http://community.opscode.com/api/v1" cookbook "ntp" cookbook "timezone", "0.0.1" cookbook "rvm", :git => "https://github.com/fnichol/chef-rvm", :ref => "v0.7.1" cookbook "cloudera", :path => "vendor/cookbooks/cloudera-cookbook"
Test our `web` cookbook In order to do that we need:
Vagrantfile Define our dependencies (use a Vagrant plugin !?) Configure chef_solo providerYou can use the Vagrant-box from last exercise (to save time)
cd path/to/project vagrant init
You should get a clean vagrant file
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "CentOS 6.5 x86_64" config.vm.box_url = "http://bit.ly/1aNaifu"
In order to save time I have provided an offline copy of this box: Add it by excuting the command Vagrant box add like so:
vagrant box add "CentOS 6.5 x86_64" file:///path/to/vbox/image-bundle.box
This command will add to your home folder ~/.vagrnat/boxes/CentOS 6.5 x86_64
vagrant box add "centos65-x86_65" /Volumes/TOSHIBADISK/Vagrant-Boxes/centos65-x86_64-20131205.box Downloading box from URL: file:/Volumes/TOSHIBADISK/Vagrant-Boxes/centos65-x86_64-20131205.box Extracting box...te: 245M/s, Estimated time remaining: --:--:--) Successfully added box 'centos65-x86_65' with provider 'virtualbox'!
librarian-chef init create Cheffile
Add your dependency
vim Cheffile
cookbook 'nginx' cookbook 'iptables'
librarian-chef config path ./chef/cookbooks --local
this will create .librarian/chef/config
cat .librarian/chef/config --- LIBRARIAN_CHEF_PATH: ./chef/cookbooks
3 options
Get a virtualbox image with chef_solo on it - vagrantbox.es Use the shell provisioner like in Exercise 03config.vm.provision "shell", inline: "[[ `which chef-solo` ]] || curl -L https://www.opscode.com/chef/install.sh | sudo bash"Use vagrant omnibus plug-in
$ vagrant plugin install vagrant-omnibus
Configure vagrant to do it ...
Vagrant.configure("2") do |config| config.omnibus.chef_version = :latest # or version: "11.4.0" ... end
config.vm.provision :chef_solo do |chef| chef.cookbooks_path = ["chef/cookbooks", "chef/site-cookbooks"] chef.log_level = ENV['CHEF_LOG'] ? ENV['CHEF_LOG'].to_sym : :info chef.add_role "web" # You may also specify custom JSON attributes: chef.json = { some_key: "value" } end
please note: you can control anything you can control in solo.rb ... proxy configuration, log level, roles, attributes etc .
#Proxy support for chef-solo, else i.e. remote_file externally will do worklibr # chef.http_proxy = "" # chef.https_proxy = "" # chef.no_proxy = "" # chef.log_level = ENV['CHEF_LOG'] ? ENV['CHEF_LOG'].to_sym : :debug
place the web cookbook into the ./chef/site-cookbooks directory
mkdir ./chef/site-cookbooks cp -R path/to/cookbook/web ./chef/site-cookbooks/
├── .librarian │ └── chef ├── Cheffile ├── Vagrantfile ├── chef │ └── site-cookbooks │ └── web
we also want to add chef/cookbooks and tmp to .gitignoreso we don't submit dependencies to source control
echo -e "chef/cookbooks\ntmp\n" > .gitignore
librarian-chef install
*if you are using vagrant-librarian-chef skip this step
librarian-chef output:
Installing apt (2.3.8) Installing rsyslog (1.11.0) Installing bluepill (2.3.1) Installing build-essential (1.4.2) Installing iptables (0.12.0) Installing ohai (1.1.12) Installing yum (3.1.0) Installing yum-epel (0.3.4) Installing runit (1.5.8) Installing nginx (2.2.2)
ls ./chef/cookbooks/ apt bluepill build-essential nginx ohai rsyslog runit yum yum-epel
Where did all that come from ?Take a look @: ./chef/coobkooks/nginx/metadata.rb
vagrant up
Vagrant output -> standard stuff ...
vagrant provision [default] Installing Chef cookbooks with Librarian-Chef... [default] The cookbook path '/Users/c5191707/Projects/tikal/chef_workshop/excersizes/ex05/roles' doesn't exist. Ignoring... [default] Running provisioner: shell... [default] Running: inline script [default] Running provisioner: chef_solo... Generating chef JSON and uploading... Running chef-solo...
[] INFO: Forking chef instance to converge... [] INFO: *** Chef 11.10.4 *** [] INFO: Chef-client pid: 3042 [] INFO: Setting the run_list to ["recipe[web]"] from JSON [] INFO: Run List is [recipe[web]] [] INFO: Run List expands to [web] [] INFO: Starting Chef Run for ex05 [] INFO: Running start handlers [] INFO: Start handlers complete. [] INFO: ohai plugins will be at: /etc/chef/ohai_plugins [] INFO: ohai[custom_plugins] reloaded
when using the vagrant librarian-chef plugin you will see:
[default] Installing Chef cookbooks with Librarian-Chef...
Vagrant output -> chef converge
[] INFO: package[nginx] installing nginx-1.0.15-5.el6 from epel repository [] INFO: package[nginx] sending reload action to ohai[reload_nginx] (immediate) [] INFO: ohai[reload_nginx] reloaded [] INFO: service[nginx] enabled [] INFO: directory[/var/log/nginx] mode changed to 755 [] INFO: directory[/etc/nginx/sites-available] created directory /etc/nginx/sites-available [] INFO: directory[/etc/nginx/sites-available] owner changed to 0 [] INFO: directory[/etc/nginx/sites-available] group changed to 0 [] INFO: directory[/etc/nginx/sites-available] mode changed to 755 [] INFO: directory[/etc/nginx/sites-enabled] created directory /etc/nginx/sites-enabled [] INFO: directory[/etc/nginx/sites-enabled] owner changed to 0 [] INFO: directory[/etc/nginx/sites-enabled] group changed to 0 [] INFO: directory[/etc/nginx/sites-enabled] mode changed to 755
[] INFO: execute[nxensite default] ran successfully [] INFO: execute[nxensite default] not queuing delayed action reload on service[nginx] (delayed), as it's already been queued [] INFO: service[nginx] started [] INFO: directory[/var/www/nginx/demo] created directory /var/www/nginx/demo [] INFO: directory[/var/www/nginx/demo] owner changed to 497 [] INFO: directory[/var/www/nginx/demo] group changed to 497
Note the "(delayed)" in the service restart Notify immediately / delayed: By default, notifications are :delayed, that is they are queued up as they are triggered, and then executed at the very end of a chef-client run. To run an action immediately, use :immediately:
[] INFO: template[/etc/nginx/sites-available/demo-site] created file /etc/nginx/sites-available/demo-site [] INFO: template[/etc/nginx/sites-available/demo-site] updated file contents /etc/nginx/sites-available/demo-site [] INFO: template[/etc/nginx/sites-available/demo-site] owner changed to 0 [] INFO: template[/etc/nginx/sites-available/demo-site] group changed to 0 [] INFO: template[/etc/nginx/sites-available/demo-site] mode changed to 644 [] INFO: template[/var/www/nginx/demo/index.html] created file /var/www/nginx/demo/index.html [] INFO: template[/var/www/nginx/demo/index.html] updated file contents /var/www/nginx/demo/index.html [] INFO: template[/var/www/nginx/demo/index.html] owner changed to 497 [] INFO: template[/var/www/nginx/demo/index.html] group changed to 497
[] INFO: execute[nxensite demo-site] ran successfully [] INFO: execute[nxensite demo-site] not queuing delayed action reload on service[nginx] (delayed), as it's already been queued [] INFO: service[iptables] disabled [] INFO: template[nginx.conf] sending reload action to service[nginx] (delayed) [] INFO: service[nginx] reloaded [] INFO: template[/etc/nginx/sites-available/demo-site] sending restart action to service[nginx] (delayed) [] INFO: service[nginx] restarted [] INFO: Chef Run complete in 28.387247187 seconds [] INFO: Running report handlers [] INFO: Report handlers complete
Disabled iptables (just in case ...) Reload nginx service
The long answer is it depends ...
Worth noting
Think of chef solo as the entire "chef-server" in a repository
. ├── README.md ├── centos_node │ ├── Vagrantfile │ └── bootstrap.sh ├── chef-server │ ├── Vagrantfile │ ├── bootstrap.sh │ └── knife-config.sh └── ubutnu_node ├── Vagrantfile └── bootstrap.sh
Available @ chef_workshop on Github[ see chef_server_rotute directory ]
We will have a chef server + 2 nodes - 1 centos, 1 ubuntu all on VirtualBox
git clone git://github.com/opscode/chef-repo.git
Provides a directory layout to be used in conjunction with knife to:
pull down / upload cookbooks
Create nodes / roles / environments etc
see example in this workshop:
install from master using chef-solo ...
cd chef_workshop/chef_server_route/chef_server vagrant up
In 3-5 minuets you have a chef server installed and chef_repo cloned under the root users directory !
The "magic" is in the ./bootstrap.sh & ./knife-config.sh files
# create required bootstrap dirs/files mkdir -p /var/chef/cache /var/chef/cookbooks/chef-server # pull down this chef-server cookbook wget -qO- https://github.com/opscode-cookbooks/chef-server/archive/master.tar.gz | tar xvzC /var/chef/cookbooks/chef-server --strip-components=1 # install chef server with chef solo chef-solo -o 'recipe[chef-server::default]'
Download the master bundle in to chef's default directories and invoke chef-solo ...
In this workshop the chef workstation will reside on our chef server
#!/bin/bash [[ -z "$DEBUG" ]] && set -x || set -e # we need git on the image to set the cookbook path in knife.rb [[ `which git` ]] || apt-get -y install git # clone the repo ... [myself :)] test -d /root/chef_repo || git clone https://github.com/tikalk-cookbooks/chef-intro-repo.git /root/chef_repo cd /etc/bash_completion.d/ test -f knife.sh || wget https://gist.github.com/raw/1050685/23624fff40694d5ed5f55089774d13b1937bb37f/knife.sh
install git, checkout the chef-repo for this example
Manual instructions how to configure knife ...*
knife configure --admin-client-name admin --admin-client-key \ /etc/chef-server/admin.pem -i -r /root/chef_repo/ \ --validation-client-name chef-validator --validation-key \ /etc/chef-server/chef-validator.pem
This is relevant to our example, in most cases you will
knife configure -i
In a "real life" situation you will need a copy of the pem files
root@chef-srv:~# knife configure --admin-client-name admin --admin-client-key /etc/chef-server/admin.pem -i -r /root/chef_repo/ --validation-client-name chef-validator --validation-key /etc/chef-server/chef-validator.pem WARNING: No knife configuration file found Where should I put the config file? [/root/.chef/knife.rb] Please enter the chef server URL: [https://chef-srv:443] https://192.168.56.101:443 Please enter a name for the new user: [vagrant] Creating initial API user... Please enter a password for the new user: Created user[vagrant] Configuration file written to /root/.chef/knife.rb
please use your ip int the chef server url "https://ipaddress:443"
log_level :info log_location STDOUT node_name 'vagrant' client_key '/root/.chef/vagrant.pem' validation_client_name 'chef-validator' validation_key '/etc/chef-server/chef-validator.pem' chef_server_url 'https://192.168.56.101:443' syntax_check_cache_path '/root/.chef/syntax_check_cache' cookbook_path [ '/root/chef_repo//cookbooks' ]
Provision a centos / ubuntu node via Vagrant ...
cd chef_workshop/chef_server_route/centos_node vagrant up cd chef_workshop/chef_server_route/ubutnu_node vagrant up
once they are up and running connect to your chef workstation
root@chef-srv:~/chef_repo$ cat roles/base.json { "name": "base", "description": "", "json_class": "Chef::Role", "default_attributes": { }, "override_attributes": { "chef_client": { "server_url": "http://192.168.56.101:443" } }, "chef_type": "role", "run_list": [ "recipe[ntp]", "recipe[chef-client]", "recipe[chef-client::delete_validation]" ], "env_run_lists": { } }
sudo -i cd ~/chef_repo
Upload role to server:
root@chef-srv:~/chef_repo$ knife role from file roles/base.json Updated Role base!
list exiting roles on the server
root@chef-srv:~/chef_repo$ knife role list base
Connect back to chef-server / workstation and provision nodes
# Bootstrap nodes centos node :: knife bootstrap 192.168.56.103 -x opencm -P opencm -r 'role[base]' --sudo ubtunu node :: knife bootstrap 192.168.56.104 -x opencm -P opencm -r 'role[base]' --sudo
opencm is a user defined on the nodes ...(during vagrant provision)
scroll to view output ...
root@chef-srv:~/chef_repo# knife bootstrap 192.168.56.104 -x opencm -P opencm -r 'role[base]' --sudo Bootstrapping Chef on 192.168.56.104 192.168.56.104 Starting Chef Client, version 11.10.4 192.168.56.104 resolving cookbooks for run list: ["ntp", "chef-client", "chef-client::delete_validation"] 192.168.56.104 Synchronizing Cookbooks: 192.168.56.104 - chef-client 192.168.56.104 - ntp 192.168.56.104 Compiling Cookbooks... 192.168.56.104 [2014-02-22T21:32:59+00:00] WARN: Chef::Mixin::Language is deprecated. Use either (or both) 192.168.56.104 Chef::DSL::PlatformIntrospection or Chef::DSL::DataQuery instead. 192.168.56.104 192.168.56.104 [2014-02-22T21:32:59+00:00] WARN: Called from: 192.168.56.104 /var/chef/cache/cookbooks/chef-client/libraries/helpers.rb:23:in `<module:helpers>' 192.168.56.104 /var/chef/cache/cookbooks/chef-client/libraries/helpers.rb:22:in `<module:chefclient>' 192.168.56.104 /var/chef/cache/cookbooks/chef-client/libraries/helpers.rb:21:in `<module:opscode>' 192.168.56.104 Converging 12 resources 192.168.56.104 Recipe: ntp::default 192.168.56.104 * package[ntp] action install 192.168.56.104 - install version 1:4.2.6.p3+dfsg-1ubuntu3.1 of package ntp 192.168.56.104 192.168.56.104 * service[ntp] action enable (up to date) 192.168.56.104 * service[ntp] action start (up to date) 192.168.56.104 * service[ntp] action restart 192.168.56.104 - restart service service[ntp] 192.168.56.104 192.168.56.104 * template[/etc/ntp.conf] action create 192.168.56.104 - update content in file /etc/ntp.conf from 4eb9a0 to a95b85 192.168.56.104 --- /etc/ntp.conf 2012-06-05 20:12:18.000000000 +0000 192.168.56.104 +++ /tmp/chef-rendered-template20140222-2637-u4910c 2014-02-22 21:33:04.957012896 +0000 192.168.56.104 @@ -1,56 +1,24 @@ 192.168.56.104 -# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help 192.168.56.104 +# Generated by Chef for node2 192.168.56.104 +# node[:fqdn] = ohai data collected on node ! 192.168.56.104 +# Local modifications will be overwritten. 192.168.56.104 192.168.56.104 -driftfile /var/lib/ntp/ntp.drift 192.168.56.104 +restrict -6 ::1 192.168.56.104 +#server 192.168.56.104 192.168.56.104 + server 0.pool.ntp.org iburst 192.168.56.104 + restrict 0.pool.ntp.org nomodify notrap noquery 192.168.56.104 + server 1.pool.ntp.org iburst 192.168.56.104 + restrict 1.pool.ntp.org nomodify notrap noquery 192.168.56.104 + server 2.pool.ntp.org iburst 192.168.56.104 + restrict 2.pool.ntp.org nomodify notrap noquery 192.168.56.104 + server 3.pool.ntp.org iburst 192.168.56.104 + restrict 3.pool.ntp.org nomodify notrap noquery 192.168.56.104 192.168.56.104 -# Enable this if you want statistics to be logged. 192.168.56.104 -#statsdir /var/log/ntpstats/ 192.168.56.104 - 192.168.56.104 -statistics loopstats peerstats clockstats 192.168.56.104 -filegen loopstats file loopstats type day enable 192.168.56.104 -filegen peerstats file peerstats type day enable 192.168.56.104 -filegen clockstats file clockstats type day enable 192.168.56.104 - 192.168.56.104 -# Specify one or more NTP servers. 192.168.56.104 - 192.168.56.104 -# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board 192.168.56.104 -# on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for 192.168.56.104 -# more information. 192.168.56.104 -server 0.ubuntu.pool.ntp.org 192.168.56.104 -server 1.ubuntu.pool.ntp.org 192.168.56.104 -server 2.ubuntu.pool.ntp.org 192.168.56.104 -server 3.ubuntu.pool.ntp.org 192.168.56.104 - 192.168.56.104 -# Use Ubuntu's ntp server as a fallback. 192.168.56.104 -server ntp.ubuntu.com 192.168.56.104 - 192.168.56.104 -# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for 192.168.56.104 -# details. The web page <http: support.ntp.org="" bin="" view="" support="" accessrestrictions=""> 192.168.56.104 -# might also be helpful. 192.168.56.104 -# 192.168.56.104 -# Note that "restrict" applies to both servers and clients, so a configuration 192.168.56.104 -# that might be intended to block requests from certain clients could also end 192.168.56.104 -# up blocking replies from your own upstream servers. 192.168.56.104 - 192.168.56.104 -# By default, exchange time with everybody, but don't allow configuration. 192.168.56.104 -restrict -4 default kod notrap nomodify nopeer noquery 192.168.56.104 -restrict -6 default kod notrap nomodify nopeer noquery 192.168.56.104 - 192.168.56.104 -# Local users may interrogate the ntp server more closely. 192.168.56.104 +restrict default kod nomodify notrap nopeer noquery 192.168.56.104 +restrict -6 default kod nomodify notrap nopeer noquery 192.168.56.104 restrict 127.0.0.1 192.168.56.104 -restrict ::1 192.168.56.104 192.168.56.104 -# Clients from this (example!) subnet have unlimited access, but only if 192.168.56.104 -# cryptographically authenticated. 192.168.56.104 -#restrict 192.168.123.0 mask 255.255.255.0 notrust 192.168.56.104 - 192.168.56.104 - 192.168.56.104 -# If you want to provide time to your local subnet, change the next line. 192.168.56.104 -# (Again, the address is an example only.) 192.168.56.104 -#broadcast 192.168.123.255 192.168.56.104 - 192.168.56.104 -# If you want to listen to time broadcasts on your local subnet, de-comment the 192.168.56.104 -# next lines. Please do this only if you trust everybody on the network! 192.168.56.104 -#disable auth 192.168.56.104 -#broadcastclient 192.168.56.104 +server 127.127.1.0 # local clock 192.168.56.104 +driftfile /var/lib/ntp/drift 192.168.56.104 +keys /etc/ntp/keys 192.168.56.104 192.168.56.104 Recipe: chef-client::service 192.168.56.104 * directory[/var/run/chef] action create 192.168.56.104 - create new directory /var/run/chef 192.168.56.104 - change mode from '' to '0755' 192.168.56.104 - change owner from '' to 'root' 192.168.56.104 - change group from '' to 'root' 192.168.56.104 192.168.56.104 * directory[/var/cache/chef] action create 192.168.56.104 - create new directory /var/cache/chef 192.168.56.104 - change mode from '' to '0755' 192.168.56.104 - change owner from '' to 'root' 192.168.56.104 - change group from '' to 'root' 192.168.56.104 192.168.56.104 * directory[/var/lib/chef] action create 192.168.56.104 - create new directory /var/lib/chef 192.168.56.104 - change mode from '' to '0755' 192.168.56.104 - change owner from '' to 'root' 192.168.56.104 - change group from '' to 'root' 192.168.56.104 192.168.56.104 * directory[/var/log/chef] action create 192.168.56.104 - create new directory /var/log/chef 192.168.56.104 - change mode from '' to '0750' 192.168.56.104 - change owner from '' to 'root' 192.168.56.104 - change group from '' to 'root' 192.168.56.104 192.168.56.104 * directory[/etc/chef] action create (up to date) 192.168.56.104 * template[/etc/init.d/chef-client] action create 192.168.56.104 - create new file /etc/init.d/chef-client 192.168.56.104 - update content in file /etc/init.d/chef-client from none to 120a45 192.168.56.104 --- /etc/init.d/chef-client 2014-02-22 21:33:05.021019559 +0000 192.168.56.104 +++ /tmp/chef-rendered-template20140222-2637-1nzg8iy 2014-02-22 21:33:05.021019559 +0000 192.168.56.104 @@ -1 +1,186 @@ 192.168.56.104 +#! /bin/sh 192.168.56.104 +### BEGIN INIT INFO 192.168.56.104 +# Provides: chef-client 192.168.56.104 +# Required-Start: $remote_fs $network 192.168.56.104 +# Required-Stop: $remote_fs $network 192.168.56.104 +# Default-Start: 2 3 4 5 192.168.56.104 +# Default-Stop: 0 1 6 192.168.56.104 +# Short-Description: Start a chef-client. 192.168.56.104 +### END INIT INFO 192.168.56.104 +# 192.168.56.104 +# Copyright (c) 2009-2010 Opscode, Inc, <legal@opscode.com> 192.168.56.104 +# 192.168.56.104 +# chef-client Startup script for chef-client. 192.168.56.104 +# chkconfig: - 99 02 192.168.56.104 +# description: starts up chef-client in daemon mode. 192.168.56.104 + 192.168.56.104 +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 192.168.56.104 +DAEMON=/usr/bin/chef-client 192.168.56.104 +NAME=chef-client 192.168.56.104 +DESC=chef-client 192.168.56.104 +PIDFILE=/var/run/chef/client.pid 192.168.56.104