Chef Server Introduction
Chef is a system and cloud infrastructure automation framework that makes it easy to deploy servers and applications to any physical, virtual, or cloud location. This guide is a simple introduction of the key concepts of chef. Extensive documentation can be found at this link
A node is any physical, virtual, or cloud machine that is configured to be maintained by a chef-client.
A workstation is a computer that is configured to run Knife, to synchronize with the chef-repo, and interact with a single Chef server. Common task developed on a workstation are:
- Developing cookbooks and recipes.
- Keeping the chef-repo synchronized with version source control.
- Using Knife to upload items from the chef-repo to the Chef server.
- Configuring organizational policy, including defining roles and environments and ensuring that critical data is stored in data bags.
- Interacting with nodes.
Knife is a command-line tool that provides an interface between a local chef-repo and the Chef server. Knife helps users to manage:
- Cookbooks and recipes.
- Stores of JSON data (data bags), including encrypted data.
- Cloud resources, including provisioning.
- The installation of the chef-client on management workstations.
- Searching of indexed data on the Chef server.
The chef-repo is the location in which the following data objects are stored:
- Cookbooks (including recipes, versions, cookbook attributes, resources, providers, libraries, and templates).
- Data bags.
- Configuration files (for clients, workstations, and servers).
The Hosted Server
The Chef server stores cookbooks, the policies that are applied to nodes, and metadata that describes each registered node that is being managed by the chef-client. Nodes use the chef-client to ask the Chef server for configuration details, such as recipes, templates, and file distributions. The chef-client then does as much of the configuration work as possible on the nodes themselves (and not on the Chef server).
A cookbook is the fundamental unit of configuration and policy distribution. Each cookbook defines a scenario and contains all of the components that are required to support that scenario, including:
- Attribute values that are set on nodes.
- Definitions that allow the creation of reusable collections of resources.
- File distributions.
- Libraries that extend the chef-client and/or provide helpers to Ruby code.
- Recipes that specify which resources to manage and the order in which those resources will be applied.
- Custom resources and providers.
- Metadata about recipes (including dependencies), version constraints, supported platforms, and so on.
In this example we use Linux Centos 6.5 as chef server. We will configure an ubuntu server as workstation and then we will deploy a c compiler on another ubuntu.
Basic Network Configuration
Chef Server Installation
Go to http://www.getchef.com/chef/install/ . Select the platform, and version. Download the rpm file and install it.
$wget https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chef-server-11.1.3-1.el6.x86_64.rpm $sudo rpm -Uvh chef-server-11.1.3-1.el6.x86_64.rpm
$sudo chef-server-ctl reconfigure
Chef workstation Installation
Go to http://www.getchef.com/chef/install/ . Select download chef-client, choose the platform and version. Follow the instructions.
$curl -L https://www.opscode.com/chef/install.sh | sudo bash
Setting up the chef Repo
$sudo apt-get install git
Clone chef Repo
$git clone git://github.com/opscode/chef-repo.git
Create .chef Directory
The .chef directory is used to store three files: knife.rb, ORGANIZATION-validator.pem and USER.pem.
Where ORGANIZATION and USER represent strings that are unique to each organization. These files must be present in the .chef directory in order for a workstation to be able to connect to a Chef server. To create the .chef directory:
$sudo mkdir -p ~/chef-repo/.chef
Add .chef to the .gitignore file to prevent uploading the contents of the .chef folder to github. For example:
$echo '.chef' >> ~/chef-repo/.gitignore
Get Config Files
Copy the files /etc/chef-server/chef-validator.pem /etc/chef-server/admin.pem from chef-server to station1 on a secure location and execute the command
knife configure --initial . this command will ask for the chef-validator.pem file location.
$ knife configure --initial Overwrite /home/manuel/.chef/knife.rb? (Y/N)y Please enter the chef server URL: [https://station1:443] https://chef-server:443 Please enter a name for the new user: [manuel] Please enter the existing admin name: [admin] Please enter the location of the existing admin's private key: [/etc/chef-server/admin.pem] Please enter the validation clientname: [chef-validator] Please enter the location of the validation key: [/etc/chef-server/chef-validator.pem] Please enter the path to a chef repository (or leave blank): Creating initial API user... Please enter a password for the new user: Created user[manuel] Configuration file written to /home/manuel/.chef/knife.rb
Add Ruby to the $PATH environment variable
$echo 'export PATH="/opt/chef/embedded/bin:$PATH"' >> ~/.bash_profile && source ~/.bash_profile
Verify the chef-client install
cd ~/chef-repo knife client list
Bootstrap a Node
A node is any physical, virtual, or cloud machine that is configured to be maintained by a chef-client. There are two ways to install the chef-client on a node so that it may be maintained by the chef-client:
- Use the knife bootstrap subcommand to bootstrap a node using the omnibus installer.
- Use an unattended install to bootstrap a node from itself, without using SSH.
This post will cover the knife bootstrap install opion
The knife bootstrap command is a common way to install the chef-client on a node. The default for this approach assumes that node can access the Chef website so that it may download the chef-client package from that location.
In this post we will bootsrap an ubuntu and setup a c compiler.
Run the bootstrap command
The knife bootstrap command is used to SSH into the target machine, and then do what is needed to allow the chef-client to run on the node. It will install the chef-client executable (if necessary), generate keys, and register the node with the Chef server. To setup the chef node execute the next command:
$ knife bootstrap db-node -x username -P password --sudo
Verify the installation:
$knife client show db-node
Opscode C compilere Cookbook
Opscode Build Essential is a github repository created by opscode team that provides out of the box c compiler provisioning. the first step is clone the cookbook and dependences repos on the workstation:
$mkdir ~/cookbooks $cd ~/cookbooks $git clone https://github.com/opscode-cookbooks/apt.git $git clone https://github.com/opscode-cookbooks/build-essential.git $git clone https://github.com/opscode-cookbooks/openssl.git $git clone https://github.com/sethvargo/chef-sugar.git
edit .chef/knife.rb and add the location of the cookbooks folder:
cookbook_path ['/home/manuel/chef-repo/cookbooks/', '/home/manuel/cookbooks']
Upload cookbooks to the chef-server:
$knife cookbook upload apt $knife cookbook upload build-essential $knife cookbook upload chef-sugar $knife cookbook upload openssl
Adding a recipe to the node run_list
We will add the c compiler recipe build-essential to the node:
$knife node run_list add db-node recipe[build-essential::default] db-node: run_list: recipe[build-essential::default] $knife node show db-node
After that we must login db-node to run the updated run-list, first at all, we will check that the system doesn't have installed the c compiler:
$ gcc The program 'gcc' is currently not installed. You can install it by typing: sudo apt-get install gcc
Now we can execute chef-client command that will connect to chef server and update node state:
After the execution we can check if the c compier was installed:
$gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.2-19ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)