< Return to Blog

Getting to Grips with Chef via Knife-solo, Berkshelf, and Vagrant ~ Part One

To get started, I've put together an example chef-repo (a.k.a 'kitchen') chef-server-with-vagrant, which was setup with knife-solo, Berkshelf, and Vagrant.

This kitchen was created by performing knife solo init . to turn the current directory into a new chef-repo. Here are the contents of this kitchen

.
├── Berksfile
├── Berksfile.lock
├── Gemfile
├── Gemfile.lock
├── MIT-LICENSE
├── README.md
├── Vagrantfile
├── chefserver
├── cookbooks
├── data_bags
├── environments
├── nodes
│   ├── chefserver.json
│   ├── vagrant.json
│   └── web.node.json
├── roles
│   ├── base.json
│   ├── chefserver.json
│   ├── node_base.json
│   └── vagrant_chefserver.json
└── site-cookbooks
    ├── apt
    │   ├── CHANGELOG.md
    │   ├── README.md
    │   ├── attributes
    │   │   └── default.rb
    │   ├── files
    │   │   └── default
    │   │       └── apt-proxy-v2.conf
    │   ├── libraries
    │   │   ├── helpers.rb
    │   │   └── network.rb
    │   ├── metadata.json
    │   ├── metadata.rb
    │   ├── providers
    │   │   ├── preference.rb
    │   │   └── repository.rb
    │   ├── recipes
    │   │   ├── cacher-client.rb
    │   │   ├── cacher-ng.rb
    │   │   └── default.rb
    │   ├── resources
    │   │   ├── preference.rb
    │   │   └── repository.rb
    │   └── templates
    │       ├── debian-6.0
    │       │   └── acng.conf.erb
    │       ├── default
    │       │   ├── 01proxy.erb
    │       │   └── acng.conf.erb
    │       └── ubuntu-10.04
    │           └── acng.conf.erb
    ├── build-essential
    │   ├── CHANGELOG.md
    │   ├── README.md
    │   ├── attributes
    │   │   └── default.rb
    │   ├── metadata.json
    │   ├── metadata.rb
    │   └── recipes
    │       ├── debian.rb
    │       ├── default.rb
    │       ├── fedora.rb
    │       ├── mac_os_x.rb
    │       ├── omnios.rb
    │       ├── rhel.rb
    │       ├── smartos.rb
    │       ├── solaris2.rb
    │       └── suse.rb
    ├── chef-client
    │   ├── CHANGELOG.md
    │   ├── README.md
    │   ├── attributes
    │   │   └── default.rb
    │   ├── files
    │   │   └── default
    │   │       └── tests
    │   │           └── minitest
    │   │               ├── config_test.rb
    │   │               ├── cron_test.rb
    │   │               ├── delete_validation_test.rb
    │   │               ├── service_test.rb
    │   │               └── support
    │   │                   └── helpers.rb
    │   ├── libraries
    │   │   └── helpers.rb
    │   ├── metadata.json
    │   ├── metadata.rb
    │   ├── recipes
    │   │   ├── arch_service.rb
    │   │   ├── bluepill_service.rb
    │   │   ├── bsd_service.rb
    │   │   ├── config.rb
    │   │   ├── cron.rb
    │   │   ├── daemontools_service.rb
    │   │   ├── default.rb
    │   │   ├── delete_validation.rb
    │   │   ├── init_service.rb
    │   │   ├── launchd_service.rb
    │   │   ├── runit_service.rb
    │   │   ├── service.rb
    │   │   ├── smf_service.rb
    │   │   ├── task.rb
    │   │   ├── upstart_service.rb
    │   │   ├── windows_service.rb
    │   │   └── winsw_service.rb
    │   └── templates
    │       ├── arch
    │       │   ├── conf.d
    │       │   │   └── chef-client.conf.erb
    │       │   └── rc.d
    │       │       └── chef-client.erb
    │       ├── default
    │       │   ├── chef-client.pill.erb
    │       │   ├── client.rb.erb
    │       │   ├── com.opscode.chef-client.plist.erb
    │       │   ├── debian
    │       │   │   ├── default
    │       │   │   │   └── chef-client.erb
    │       │   │   ├── init
    │       │   │   │   └── chef-client.conf.erb
    │       │   │   └── init.d
    │       │   │       └── chef-client.erb
    │       │   ├── redhat
    │       │   │   ├── init.d
    │       │   │   │   └── chef-client.erb
    │       │   │   └── sysconfig
    │       │   │       └── chef-client.erb
    │       │   ├── solaris
    │       │   │   ├── chef-client.erb
    │       │   │   └── manifest.xml.erb
    │       │   ├── suse
    │       │   │   ├── init.d
    │       │   │   │   └── chef-client.erb
    │       │   │   └── sysconfig
    │       │   │       └── chef-client.erb
    │       │   ├── sv-chef-client-log-run.erb
    │       │   └── sv-chef-client-run.erb
    │       └── windows
    │           └── chef-client.xml.erb
    ├── chef-server
    │   ├── Berksfile
    │   ├── CHANGELOG.md
    │   ├── CONTRIBUTING.md
    │   ├── LICENSE
    │   ├── README.md
    │   ├── TESTING.md
    │   ├── Thorfile
    │   ├── Vagrantfile
    │   ├── attributes
    │   │   └── default.rb
    │   ├── chefignore
    │   ├── libraries
    │   │   ├── dev_helper.rb
    │   │   └── omnitruck_client.rb
    │   ├── metadata.rb
    │   ├── recipes
    │   │   ├── default.rb
    │   │   └── dev.rb
    │   └── templates
    │       └── default
    │           └── chef-server.rb.erb
    ├── cron
    │   ├── CHANGELOG.md
    │   ├── README.md
    │   ├── metadata.json
    │   ├── metadata.rb
    │   ├── providers
    │   │   └── d.rb
    │   ├── recipes
    │   │   ├── default.rb
    │   │   └── test.rb
    │   ├── resources
    │   │   └── d.rb
    │   └── templates
    │       └── default
    │           └── cron.d.erb
    ├── logrotate
    │   ├── CHANGELOG.md
    │   ├── README.md
    │   ├── attributes
    │   │   └── default.rb
    │   ├── definitions
    │   │   └── logrotate_app.rb
    │   ├── libraries
    │   │   └── logrotate_config.rb
    │   ├── metadata.json
    │   ├── metadata.rb
    │   ├── recipes
    │   │   ├── default.rb
    │   │   └── global.rb
    │   └── templates
    │       └── default
    │           ├── logrotate-global.erb
    │           └── logrotate.erb
    ├── omnibus_updater
    │   ├── CHANGELOG.md
    │   ├── Cheffile
    │   ├── Cheffile.lock
    │   ├── Gemfile
    │   ├── Gemfile.lock
    │   ├── README.md
    │   ├── attributes
    │   │   └── default.rb
    │   ├── libraries
    │   │   ├── omnibus_checker.rb
    │   │   └── omnitrucker.rb
    │   ├── metadata.json
    │   ├── metadata.rb
    │   └── recipes
    │       ├── default.rb
    │       ├── downloader.rb
    │       ├── installer.rb
    │       ├── old_package_cleaner.rb
    │       └── remove_chef_system_gem.rb
    └── vim
        ├── README.md
        ├── attributes
        │   └── default.rb
        ├── metadata.json
        ├── metadata.rb
        └── recipes
            └── default.rb

73 directories, 150 files

Get started with the README.md and once you're all setup, start off with

vagrant up

This will spawn three virtual instances

* chef              # Visit http://10.33.33.33, this is our test chef server
* chef_client       # Bootstrap your first node @ 10.33.33.50
* chefserver        # Use Knife-solo to bootstrap a chef server @ 10.33.33.40; 

The focus of this example is to be able to play with an example Chef-server, and this will be made available at http://10.33.33.33. For the purposes of this demo, the chef-server is forced to operate over HTTP rather than HTTPS, which needs an SSL certificate.

Follow the README.md to upload the various roles to the chef server — for this example, we will only be dealing with roles. Typically, you will also upload cookbooks, nodes etc. to the chef server.

You can then proceed to bootstrap a new node using your knife

-> % knife bootstrap 10.33.33.50 -x vagrant -P vagrant --sudo --node-name web.node
Bootstrapping Chef on 10.33.33.50
10.33.33.50 --2013-11-11 13:19:33--  https://www.opscode.com/chef/install.sh
10.33.33.50 Resolving www.opscode.com (www.opscode.com)... 184.106.28.82
10.33.33.50 Connecting to www.opscode.com (www.opscode.com)|184.106.28.82|:443... connected.
10.33.33.50 HTTP request sent, awaiting response... 200 OK
10.33.33.50 Length: 6790 (6.6K) [application/x-sh]
10.33.33.50 Saving to: `STDOUT'
10.33.33.50
100%[======================================>] 6,790       --.-K/s   in 0s
10.33.33.50
10.33.33.50 2013-11-11 13:19:35 (1.19 GB/s) - written to stdout [6790/6790]
10.33.33.50
10.33.33.50 Downloading Chef 11.8.0 for ubuntu...
10.33.33.50 Installing Chef 11.8.0
10.33.33.50 Selecting previously unselected package chef.
(Reading database ... 51095 files and directories currently installed.)
10.33.33.50 Unpacking chef (from .../chef_11.8.0_amd64.deb) ...
10.33.33.50 Setting up chef (11.8.0-1.ubuntu.12.04) ...
10.33.33.50 Thank you for installing Chef!
10.33.33.50 Starting Chef Client, version 11.8.0
10.33.33.50 Creating a new client identity for web.node using the validator key.
10.33.33.50 resolving cookbooks for run list: []
10.33.33.50 Synchronizing Cookbooks:
10.33.33.50 Compiling Cookbooks...
10.33.33.50 [2013-11-11T13:20:37+00:00] WARN: Node web.node has an empty run list.
10.33.33.50 Converging 0 resources
10.33.33.50 Chef Client finished, 0 resources updated

You will notice you didn't have to do anything to create the example chef server, so how does one setup a chef server on a VPS? Simple, use your knife to do that!

The third virtual environment chefserver is there for this purpose; it is a vanilla installation of Ubuntu Precise 64 (12.04 LTS). Once again, simply follow the README.md to bootstrap a working chef-server on the chefserver node using your knife. The Opscode Omnibus installer makes bootstrapping new nodes a breeze.

Troubleshooting Vagrant

Use vagrant long enough and you'll experience vagrant up hanging at "Waiting for VM to boot. This can take a few minutes"; thankfully the vagrant wiki has suggestions on tackling this.

Powering the VM down, booting with Virtualbox directly ensuring only the NAT interface is enabled — allowed me to login with u/p as vagrant/vagrant to run

$ sudo rm -Rf /var/lib/dhcp/*
$ sudo /etc/init.d/networking restart

This worked as vagrant up managed to bring the VM back online (as headless).