[Ruby] Chef tutorial

12 minute read

In this tutorial, you will learn about ** Chef ** and learn how to use Chef to set up, build and deploy a simple ** React.js ** site on ** Alibaba Cloud **.

  • This blog is a translation from the English version. You can check the original from here. We use some machine translation. We would appreciate it if you could point out any translation errors. *


To follow this tutorial, you need the following:

–Two Alibaba Cloud Elastic Compute Service (ECS) instances are installed on Ubuntu 16.04 and have at least 2GB of RAM. One of these instances will be used for the Chef node and the other for the Chef server. Also, make sure ports 22, 80, and 443 are open on these instances.
–Fully qualified registration domain (or FDQN) used for both Chef nodes and servers. Buy Alibaba Cloud Domain or go to Freenom You can get it for free.

Get to know Chef

Chef is made up of several different components. It’s important to understand these components, so let’s take a quick look at the three main components of Chef.

-** Chef Server : This component acts as a hub for configuration data, storing all configuration recipes, cookbooks, policies applied to nodes, and metadata describing each registered node managed by Chef. Serves as a central location. This component is also the central machine used by all other machines (or nodes) in your organization for deployment configuration purposes.
Nodes : The important components of a node are physical or virtual and can be understood as machines that can be managed using Chef. Chef-client is installed on each node and is used to set each node to the desired state. The node uses chef-client to interact with the chef server to get configuration information such as recipes, templates, and file distribution.
Workstation **: The Chef workstation is where you create or edit Chef configuration information. The config file is pushed to the Chef server and can be deployed to any node. To interact with the Chef server from your workstation, use the knife and chef command line tools. It is done using.

Environment settings

It’s finally time to do something practical. In this tutorial, you’ll set up your environment and install the tools you need to build a React.js application using chef.

Workstation settings

The workstation is basically the place to author the Chef configuration details. The workstation can be any OS of your choice. In other words, Linux, MacOS, and Windows all work here.

  1. Install the ChefDK package. The Chef DK (Development Kit) contains all the tools you need to develop and test your infrastructure. At the time of writing this tutorial, I am using the current stable version (4.0.60). Click this link (https://downloads.chef.io/chefdk/?spm=a2c65.11461447.0.0.10585fa7zubQyM) to download the Chef DK based on your OS.

  2. Make sure you have installed the Chef DK and that you can access the Chef DK from the command line. To do this, you can run chef —version to verify the installation.

 [email protected]:~$ chef --version
   Chef Development Kit Version: 4.0.60
   chef-client version: 15.0.300
   delivery version: master
   berks version: 7.0.8
   kitchen version: 2.2.5
   inspec version: 4.3.2
  1. For Mac and Linux users, you need to make sure that the Ruby version included in the Chef development kit is set as the default Ruby version. To do this, follow the steps below.

–Open a terminal and run which ruby. You should get the following result:

   [email protected]:~$ which ruby

–You need to set the Ruby included in ChefDK as the system Ruby using the chef shell-init subcommand. The application used by ChefDK can be isolated from other Ruby development tools that may also be on your workstation.

  [email protected]:~$ echo 'eval "$(chef shell-init bash)"' >> ~/.bash_profile && source ~/.bash_profile

If you are using a different shell than bash, such as zsh, fish, or Windows PowerShell (posh), replace SHELL_NAME with the shell and SHELL_PROFILE with the shell profile and run the following command: please.

 [email protected]:~$ echo 'eval "$(chef shell-init SHELL_NAME)"' >> ~/.SHELL_PROFILE && source ~/.SHELL_PROFILE

–If you run the which ruby command again and confirm that you are using the Chef development kit version of ruby, you should get output similar to the following.

  [email protected]:~$ which ruby
  1. Next, you need to create a working directory called react-app-repo for your workstation. You will use the chef generate repo repo_name command for this. This will create the file and folder structure that Chef needs.
 [email protected]:~$ chef generate repo react-app-repo && cd react-app-repo
  1. Now that you have configured your workstation, configure and configure your Chef server.

Chef server settings

To set up your Chef server, follow these steps:

  1. Spin up an Alibaba Cloud ECS instance installed on Ubuntu 16.04 as a Chef server and make sure ports 80, 22, and 443 are open. If you’re running a Chef server in the cloud, make sure these ports are open through security groups.

  2. The Chef server requires a resolvable domain and host name. You need to make sure that the host name on the server matches the public host name. This is possible by running the following command:

  [email protected]_server:~$ echo YOUR_DOMAIN_NAME | xargs sudo hostname
  1. For learning purposes, I created the following bash script for this tutorial. This should help you download and install the Chef-server package.

–Copy the following script to the path /tmp/installChefServer.sh on the server.

   [email protected]_server:~$ sudo vi /tmp/installChefServer.sh
      #!/usr/bin/env bash


      updateLinuxPackages() {
        printf "${BOLD}${GREEN}=================================== Updating all packages ============================================ ${NC}\n"
        apt-get update


      createDirectories() {
        if [ ! -d /creds ]; then
          mkdir /creds
        if [ ! -d /downloads ]; then
          mkdir /downloads

      downloadAndInstallChefServer() {
        if [ ! -f /downloads/chef-server-core_12.19.26-1_amd64.deb ]; then
          printf "${BOLD}${GREEN}=================================== Downloading the Chef server package... ================== ${NC}\n"
          wget -nv -P /downloads https://packages.chef.io/files/stable/chef-server/12.19.26/ubuntu/16.04/chef-server-core_12.19.26-1_amd64.deb

        if [ ! $(which chef-server-ctl) ]; then
          printf "${BOLD}${GREEN}=================================== Installing Chef server =================================== ${NC}\n"
          dpkg -i /downloads/chef-server-core_12.19.26-1_amd64.deb
          chef-server-ctl reconfigure

          printf "${BOLD}${GREEN}=================================== Waiting for services ====================================== ${NC}\n"
          until (curl -D - http://localhost:8000/_status) | grep "200 OK"; do sleep 15s; done
          while (curl http://localhost:8000/_status) | grep "fail"; do sleep 15s; done

          printf "${BOLD}${GREEN}============================= Creating user ========================== ${NC}\n"
          # creating user format: chef-server-ctl user-create USER_NAME FIRST_NAME LAST_NAME EMAIL 'PASSWORD' --filename FILE_NAME
          chef-server-ctl user-create admin admin admin [email protected] 'notsecure' --filename /creds/chefadmin.pem
          printf "${BOLD}${GREEN}============================= Creating oganization with user ========================== ${NC}\n"
          # creating org format: chef-server-ctl org-create SHORT_ORG_NAME 'FULL_ORG_NAME' --association_user USER_NAME --filename FILE_NAME
          chef-server-ctl org-create chef "Chef-learn, Inc." --association_user admin --filename organization-validator.pem
          printf "${BOLD}${GREEN}============================= Adding Web UI for chef  ========================== ${NC}\n"
          chef-server-ctl install chef-manage
          chef-server-ctl reconfigure
          chef-manage-ctl reconfigure --accept-license

        printf "${BOLD}${GREEN}==================================== Your Chef server is ready! ================================== ${NC}\n"

      main() {


–This script also creates a user with the following information:

–Username: admin

–Execute the following command to make the script executable.

  [email protected]_server:~$ sudo chmod u+x /tmp/installChefServer.sh

–Finally, run the script. It may take some time.

  [email protected]_server:~$ sudo /tmp/installChefServer.sh
  1. You can access the Chef web interface on your browser by host name.


Configure your workstation to communicate with Chef Server

Utilize the Knife utility tool already included in the Chef DK to establish communication between your workstation and the Chef server.

Basically, Knife needs two files to authenticate the Chef server.

–The knife configuration file knife.rb contains information such as the URL of the Chef server, the location of the RSA private key (SSH key), and the default location of the cookbook.

–The RSA private key is used to authenticate all requests sent to the Chef server. The public key is held by the Chef server and the private key is held by the workstation.

To establish communication between your workstation and the Chef server, follow these steps:

  1. Run the knife configure command to create the knife configuration.

Replace YOUR-HOST-NAME with the chef-server domain name and SHORT-ORG-NAME with chef. Also, make a note of the path specified in the output for placing the client key.

  [email protected]:~$ knife configure
    WARNING: No knife configuration file found. See https://docs.chef.io/config_rb_knife.html for details.
    Please enter the chef server URL: [https://devops1c.mylabserver.com/organizations/chef]: https://YOUR-HOST-NAME/organizations/SHORT-ORG-NAME
    Please enter an existing username or clientname for the API: [user] admin
    You must place your client key in:
    Before running commands with Knife

    Configuration file written to /home/user/.chef/credentials
  1. You need to create a knife.rb file in your react-app-repo directory to make sure the knife knows the location of the cookbooks.
  [email protected]:~$ mkdir .chef && echo 'cookbook_path ["#{File.dirname(__FILE__)}/../cookbooks"]' >> .chef/knife.rb

You also need to copy the SSH key file you created when you created the user with the ʻinstallChefServer.sh script from chef-server to your workstation using the scp` command.

Note ~ / .chef / admin.pem is the path specified to put the client key, but change it if it is different from the path specified in the output of the knife configure command.

Then replace it with the following item.

Replace ʻIP-ADDRESS-OR-HOSTNAME` with the public IP address / hostname of chef-server.

Replace ʻUSER` with your Chef server username.

Replace PATH_TO_YOUR_SSH_KEY with the path to the Chef server’s ssh-key.

   [email protected]:~$ scp -i PATH_TO_YOUR_SSH_KEY [email protected]:/creds/chefadmin.pem ~/.chef/admin.pem

Alternatively, if you are using a password as an authentication method to gain access to the server, you can also run the following command:

 [email protected]:~$ scp [email protected]:/creds/chefadmin.pem ~/.chef/admin.pem
  1. Next, you need to get and validate the SSL certificate from the Chef server using the following command.
[email protected]:~$ knife ssl fetch
    WARNING: Certificates from www.mydomainname.com will be fetched and placed in your trusted_cert
    directory (/home/user/.chef/trusted_certs).

    Knife has no means to verify these are the correct certificates. You should
    verify the authenticity of these certificates after downloading.

    Adding certificate for www_mydomainname_com in /home/user/.chef/trusted_certs/www_mydomainname_com.crt

Run the knife ssl check command to check the SSL configuration.

  [email protected]:~$ knife ssl check
     Connecting to host ec2-34-207-124-26.compute-1.amazonaws.com:443
     Successfully verified certificates from ec2-34-207-124-26.compute-1.amazonaws.com

Now that you’ve set up your workstation, you can use the knife to connect to the Chef server. In the next part, you will configure the nodes.

Node settings and bootstrap

Before you start managing your settings in Chef, you need a node to work with. To do this, create another ECS instance with Ubuntu 16.04 installed and use the Knife and bootstrap subcommands from your workstation. Just create a node server and most of the work will be done from workstation.

  1. Create another Alibaba Cloud instance with Ubuntu 16.04 installed and make sure ports 80, 22, 443 and 3000 are open. The react.js application runs on port 3000.

  2. You need to run the following command to verify that the host name of the node server matches the public host name.

Let’s replace it with:

–ʻIP-ADDRESS-OR-Replace HOSTNAME` with the public IP address / hostname of the node server.

–ʻUSER` with the name of the user on the node server

–Specify the path to the node server ssh-key in PATH_TO_YOUR_SSH_KEY.

 [email protected]:~$ ssh -i PATH_TO_YOUR_SSH_KEY [email protected] 'echo YOUR_DOMAIN_NAME | xargs sudo hostname'
  1. To bootstrap the new cloud server from your workstation to a node managed by the Chef server, run the following command:


–ʻIP-ADDRESS-OR-Replace HOSTNAME` with the public IP address / hostname of the node server.

–ʻUSER` with the name of the user on the node server

–Specify the path to the node server ssh-key in PATH_TO_YOUR_SSH_KEY.

–Specify node_name with reactJS-node. Understand that node_name is the name you want to give to the node.

 [email protected]:~$ knife bootstrap IP-ADDRESS-OR-HOSTNAME --connection-user USER --sudo -i PATH_TO_YOUR_SSH_KEY --node-name NODE-NAME
    [] -----> Installing Chef Omnibus (stable/15)
    [] downloading https://omnitruck.chef.io/chef/install.sh
    [] Getting information for chef stable 15 for ubuntu...
    [] Installing chef 15
    [] Thank you for installing Chef Infra Client! For help getting started visit https://learn.chef.io
    [] Starting the first Chef Infra Client Client run...
    [] +---------------------------------------------+
    []  2 product licenses accepted.
    [] +---------------------------------------------+
    [] Starting Chef Infra Client, version 15.0.300
    [] resolving cookbooks for run list: []
    [] Synchronizing Cookbooks:
    [] Installing Cookbook Gems:
    [] Compiling Cookbooks...
    [] [2019-07-01T06:52:36+00:00] WARN: Node reactJS-node has an empty run list.
    [] Converging 0 resources
    [] Running handlers:
    [] Running handlers complete
    [] Chef Infra Client finished, 0/0 resources updated in 02 seconds

Alternatively, if you are using a password as an authentication method to gain access to the server, run the following command.

 [email protected]:~$ knife bootstrap IP-ADDRESS-OR-HOSTNAME -N NODE_NAME -x USER -P 'PASSWORD' --sudo
  1. To verify that your node is associated with the Chef server, run the knife node list command.
 [email protected]:~$ knife node list

You can see the node data by running the knife node show command.

knife node show NODE-NAME
[email protected]:~$ knife node show reactJS-node
   Node Name:   reactJS-node
   Environment: _default
   FQDN:        ip-172-31-56-238.home.internal
   Run List:    
   Platform:    ubuntu 16.04

Build React.js application

Now that you’ve set up your chef server, workstations, and nodes, you’re ready to build your react.js application. You will write a cookbook like the one below.

–Set up and install node.js
–Install pm2. pm2 is a process manager that helps keep the react.js app running.
–Install the react.js application.

–Launch the react.js application.

You will use chef execute and bash resources for that. Both of these resources are used to execute commands and scripts. The ʻexecute resource is used to execute a single command, and the bash` resource is used to execute a multi-line command. For syntax and property details, see the execute and bash resources Please refer to the documentation.

Open the default.rb file located in the cookbooks / example / attributes / recipes directory on your workstation and replace it as follows:

bash 'Install Node.js' do
 cwd "/home/ubuntu"
 code <<-EOH
   curl -sL https://deb.nodesource.com/setup_8.x -o nodesource_setup.sh
   bash nodesource_setup.sh
   apt-get install nodejs -y 

execute 'Install pm2' do
 cwd "/home/ubuntu"
 command 'npm install pm2 -g'

execute 'Setup react app' do
 cwd "/home/ubuntu"
 command 'npx create-react-app my-app'
 only_if do ! File.exist?('/home/ubuntu/my-app') end

bash 'Start application' do
 cwd "/home/ubuntu"
 code <<-EOH
   cd my-app
   pm2 start npm -- start

In order to run the cookbook, you need to upload it to the Chef server. Please note that you will need to re-upload each time you make changes to this file. Make sure it is in the react-app-repo directory and run this command.

[email protected]:~$ knife upload cookbooks/example

You need to add the Cookbook’recipe to the node's run_list` using the following command:

[email protected]:~$ knife node run_list add reactJS-node 'recipe[example]'
  run_list: recipe[example]

Details of run_list can be found in the Documentation (https://docs.chef.io/run_lists/).

Now, use the knife ssh command to deploy the cookbook to reactJS-node.

Then replace it as follows:

–Replace ʻUSER` with the username on the node server.

–Specify the path to the node server ssh-key in PATH_TO_YOUR_SSH_KEY.

[email protected]:~$ knife ssh 'name:reactJS-node' 'sudo chef-client' --ssh-user USER --ssh-identity-file PATH_TO_YOUR_SSH_KEY

You can now access the react.js application by pasting http: // NODE_SERVER_IP_ADDRESS: 3000 into your browser window. You should see a page like this.



This guide provides a flexible foundation for getting started with Chef. For more information on Chef, see Chef’s Official Documentation (https://docs.chef.io/?spm=a2c65.11461447.0.0.10585fa7zubQyM) and Learn Chef rally (https://learn). Please see from .chef.io/?spm=a2c65.11461447.0.0.10585fa7zubQyM # /).

  • Alibaba Cloud is the No. 1 (2019 Gartner) cloud infrastructure operator in the Asia-Pacific region with two data centers in Japan and more than 60 availability zones in the world.
    Click here for more information on Alibaba Cloud.
    Alibaba Cloud Japan Official Page *