By Kehinde Sanni, Alibaba Cloud Community Blog author.
Chef is an open-source configuration management tool written in Ruby and Erlang. It uses a pure-Ruby, domain-specific language (DSL) for writing system configuration. Chef transforms infrastructure into code so to help automate server deployment and management. So, whether you're operating in the cloud, on-premises, or in a hybrid environment, Chef can help you to automate your infrastructure, helping to configure, deploy, and manage it across your network, no matter its size.
In this tutorial, you will learn the basics of Chef, and build a simple React.js site using Chef on an Alibaba Cloud ECS instance with Ubuntu installed. By the end of this tutorial, you'll have learned the basics of Chef, how to set up a Chef server, node and workstation, and be able to deploy a minimal application.
To follow this tutorial, you will need:
Chef is made up of several different components. It's important to understand these components, so here let's quickly look at the three major components of Chef.
Now it's time to do something practical. In this leg of the tutorial, you will set up your environment and install the necessary tools required to build your React.js application with chef.
Recall that your workstation is basically where you author your chef configuration details. Your workstation can be any OS you choose be it. So, Linux, MacOS, and Windows all work here.
1. Install the ChefDK package. The Chef DK (Development Kit) contains all the tools you will need to develop and test your infrastructure. You are
using the current stable version, which is 4.0.60 as at the time of my writing this tutorial. Click on this link to download the Chef DK based on your OS.
2. Verify that you have installed Chef DK and ensure that you can access the Chef DK from your command line. To do this, you can run chef --version
to verify your installation.
chef@workstation:~$ 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
3. For Mac and Linux users, you need to ensure that the version of Ruby that is included with your Chef development kit is configured as the default version of Ruby. To do this, follow these steps:
which ruby
. You should get something similar to the result as shown below chef@workstation:~$ which ruby
/usr/bin/ruby
Using the chef shell-init
sub-command, you will need to set the Ruby included in ChefDK as the system Ruby. ChefDK allows for applications used by chefDK to be isolated from other Ruby development tools, which may also be present on the workstation.
chef@workstation:~$ echo 'eval "$(chef shell-init bash)"' >> ~/.bash_profile && source ~/.bash_profile
If you're using a shell different from bash such as zsh
, fish
, or Windows PowerShell (posh), run the command below, replacing SHELL_NAME
with your shell and .SHELL_PROFILE
with your shell profile.
chef@workstation:~$ echo 'eval "$(chef shell-init SHELL_NAME)"' >> ~/.SHELL_PROFILE && source ~/.SHELL_PROFILE
which ruby
command again to confirm you are using the Chef development kit version of ruby and you should get the output shown below. chef@workstation:~$ which ruby
/opt/chefdk/embedded/bin/ruby
4. Next, you will need to create a working directory, which will specifically be react-app-repo
for your workstation. You are going to use the chef generate repo REPO_NAME
command for this. This would create the necessary files and folder structure required by Chef.
chef@workstation:~$ chef generate repo react-app-repo && cd react-app-repo
5. Now that you are done setting up the workstation, you will go ahead to set up and configure the Chef server.
To set up your Chef server, you can follow these steps:
1. Spin up an Alibaba Cloud ECS instance installed with Ubuntu 16.04 as the Chef server and ensure port 80, 22 and 443 are open. If you're running Chef server in the cloud, ensure these ports are open through your security group.
2. Your Chef server must have a resolvable domain and hostname. You will need to ensure that your server's hostname matches it public hostname. You can do so by running the command below:
chef@chef_server:~$ echo YOUR_DOMAIN_NAME | xargs sudo hostname
3. For learning purposes, I've created a bash script below for this tutorial. This should be helpful for you when it comes to downloading and installing the Chef-server package:
/tmp/installChefServer.sh
on your server chef@chef_server:~$ sudo vi /tmp/installChefServer.sh
bash
#!/usr/bin/env bash
BOLD='\e[1m'
GREEN='\e[92m'
NC='\e[0m'
updateLinuxPackages() {
printf "${BOLD}${GREEN}=================================== Updating all packages ============================================ ${NC}\n"
apt-get update
}
createDirectories() {
if [ ! -d /creds ]; then
mkdir /creds
fi
if [ ! -d /downloads ]; then
mkdir /downloads
fi
}
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
fi
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 admin@example.com '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
fi
printf "${BOLD}${GREEN}==================================== Your Chef server is ready! ================================== ${NC}\n"
}
main() {
updateLinuxPackages
createDirectories
downloadAndInstallChefServer
}
main
This script also creates a user with the following information:
Password: notsecure
chef@chef_server:~$ sudo chmod u+x /tmp/installChefServer.sh
chef@chef_server:~$ sudo /tmp/installChefServer.sh
4. You can access the Chef web interface on your browser with your hostname.
To establish communication between your workstation and the Chef server, you are going utilize the Knife
utility tools already included with the ChefDK.
Basically, Knife requires two files to authenticate which the Chef server
knife.rb
, which contains information such as the Chef server's URL, the location of your RSA private key (SSH key), and the default location of your cookbooks.Follow the steps below to establish communication between the workstation and Chef server
1. Create the knife configuration by running the knife configure
command.
Replace YOUR-HOST-NAME
with your chef-server domain name and SHORT-ORG-NAME
with chef
. Also, keep a note of the path specified in the output to place the client key. you will use that next.
chef@workstation:~$ 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:
/home/user/.chef/chefadmin.pem
Before running commands with Knife
*****
Configuration file written to /home/user/.chef/credentials
2. You will need to create a knife.rb
file in your react-app-repo
directory to ensure that knife knows the location of your cookbooks
.
chef@workstation:~$ mkdir .chef && echo 'cookbook_path ["#{File.dirname(__FILE__)}/../cookbooks"]' >> .chef/knife.rb
You also need to copy over the SSH key file you created when you created your user with the installChefServer.sh
script using scp
command from your chef-server to your workstation.
Note ~/.chef/admin.pem
is the path specified to place the client key, change this if it's different from the path specified on the output of your knife configure
command.
Then, replace with following items:
IP-ADDRESS-OR-HOSTNAME
replace with the public IP-address/hostname of your chef-server
USER
replace with the name of the user on your chef-server
PATH_TO_YOUR_SSH_KEY
replace with the path to your chef-server ssh-key
chef@workstation:~$ scp -i PATH_TO_YOUR_SSH_KEY USER@YOUR-IP-ADDRESS-OR-HOSTNAME:/creds/chefadmin.pem ~/.chef/admin.pem
Alternatively, you can run the command below if you are using password as means of authentication to gain access to your server.
chef@workstation:~$ scp USER@YOUR-IP-ADDRESS-OR-HOSTNAME:/creds/chefadmin.pem ~/.chef/admin.pem
3. Next, you will need to fetch and validate the SSL certificate from your Chef server using the command below
chef@workstation:~$ 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 verify the SSL configuration.
chef@workstation:~$ 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 your workstation is set up and you can connect to the Chef server using knife. In the next part, you'll set up the node
Before you can start working with Chef to manage configuration, you will need to have a node to work with. To do this, you'll create another ECS instance with Ubuntu 16.04 installed, and utilize the Knife
and bootstrap
subcommand from your workstation. You just need to create the Node server and most of the work will be done from the workstation
1. Create another Alibaba Cloud instance with Ubuntu 16.04 installed, and ensure port 80, 22, 443 and 3000 are open. Your react.js application will run on port 3000.
2. You need to make sure your node server hostname matches it public hostname by running the command below
Now, replace the following:
IP-ADDRESS-OR-HOSTNAME
to the public IP-address/hostname of your node-server
USER
with the name of the user on your node-server
PATH_TO_YOUR_SSH_KEY
with the path to your node-server ssh-key chef@workstation:~$ ssh -i PATH_TO_YOUR_SSH_KEY USER@YOUR-IP-ADDRESS-OR-HOSTNAME 'echo YOUR_DOMAIN_NAME | xargs sudo hostname'
3. To bootstrap your new cloud server to be a node managed by your Chef server, from your workstation, you'll run the command below.
In the following, replace:
IP-ADDRESS-OR-HOSTNAME
with the public IP-address/hostname of your node-server
USER
with the name of the user on your node-server
PATH_TO_YOUR_SSH_KEY
with the path to your node-server ssh-key
NODE_NAME
with reactJS-node
. Understand that NODE_NAME
is the name you want to give your node. chef@workstation:~$ knife bootstrap IP-ADDRESS-OR-HOSTNAME --connection-user USER --sudo -i PATH_TO_YOUR_SSH_KEY --node-name NODE-NAME
Bootstrapping 34.76.3.167
[34.76.3.167] -----> Installing Chef Omnibus (stable/15)
[34.76.3.167]
[34.76.3.167] downloading https://omnitruck.chef.io/chef/install.sh
......
[34.76.3.167] Getting information for chef stable 15 for ubuntu...
[34.76.3.167] Installing chef 15
[34.76.3.167]
[34.76.3.167]
[34.76.3.167] Thank you for installing Chef Infra Client! For help getting started visit https://learn.chef.io
[34.76.3.167]
[34.76.3.167] Starting the first Chef Infra Client Client run...
[34.76.3.167]
[34.76.3.167] +---------------------------------------------+
[34.76.3.167]
[34.76.3.167] 2 product licenses accepted.
[34.76.3.167]
[34.76.3.167] +---------------------------------------------+
[34.76.3.167]
[34.76.3.167] Starting Chef Infra Client, version 15.0.300
[34.76.3.167]
[34.76.3.167] resolving cookbooks for run list: []
[34.76.3.167] Synchronizing Cookbooks:
[34.76.3.167] Installing Cookbook Gems:
[34.76.3.167] Compiling Cookbooks...
[34.76.3.167] [2019-07-01T06:52:36+00:00] WARN: Node reactJS-node has an empty run list.
[34.76.3.167] Converging 0 resources
........
[34.76.3.167] Running handlers:
[34.76.3.167]
[34.76.3.167] Running handlers complete
[34.76.3.167] Chef Infra Client finished, 0/0 resources updated in 02 seconds
Alternatively, run the command below if you are using password as means of authentication to gain access to your server
chef@workstation:~$ knife bootstrap IP-ADDRESS-OR-HOSTNAME -N NODE_NAME -x USER -P 'PASSWORD' --sudo
4. To verify that your node has been associated with the Chef server, run the knife node list
command.
chef@workstation:~$ knife node list
reactJS-node
You can view the data of your node by running the knife node show
command
knife node show NODE-NAME
chef@workstation:~$ knife node show reactJS-node
Node Name: reactJS-node
Environment: _default
FQDN: ip-172-31-56-238.home.internal
IP: 41.215.245.118
Run List:
Roles:
Recipes:
Platform: ubuntu 16.04
Tags:
With your chef server, workstation and node setup, you are now ready to build your react.js application. You are going to write a cookbook that does the following:
pm2
is a process manager that helps keep your react.js app alive and runningYou are going to use the chef execute and bash resource to do that. These resources are both used for running command or script. You'll be using the execute
resource to run a single command and the bash
resource to run a multi-line command. Feel free to go through the execute and bash resource documentation for more details on its syntax and properties.
Open the default.rb
file in the cookbooks/example/attributes/recipes
directory on your workstation and replace it with this:
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
EOH
end
execute 'Install pm2' do
cwd "/home/ubuntu"
command 'npm install pm2 -g'
end
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
end
bash 'Start application' do
cwd "/home/ubuntu"
code <<-EOH
cd my-app
pm2 start npm -- start
EOH
end
In order to run your cookbook, you will have to upload it to the chef-server. Note that each time you make changes to this file, you have to re-upload it. Ensure you are in the react-app-repo
directory and run this command:
chef@workstation:~$ knife upload cookbooks/example
You will need to add the cookbook recipe
to your node run_list
using the command below:
chef@workstation:~$ knife node run_list add reactJS-node 'recipe[example]'
reactJS-node:
run_list: recipe[example]
You can check on the documentation for more information on run_list
.
Now, you can deploy the cookbook to your reactJS-node
node using the knife ssh
command.
And you'll want to replace the following:
USER
with the name of the user on your node-server
PATH_TO_YOUR_SSH_KEY
with the path to your node-server ssh-key
chef@workstation:~$ 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 your http://NODE_SERVER_IP_ADDRESS:3000
into a browser window. You should see a page like this one:
This guide provides a flexible foundation on getting started with chef. For more information on Chef, you can refer to the official chef documentation and from learn chef rally.
Test Your Ansible Deployment with Inspec and Kitchen on Alibaba Cloud
2,599 posts | 762 followers
FollowAlibaba Clouder - July 24, 2020
Alibaba Clouder - June 14, 2019
Alibaba Clouder - September 7, 2020
Alibaba Clouder - July 5, 2019
Alibaba Clouder - June 14, 2019
Alibaba Clouder - October 12, 2019
2,599 posts | 762 followers
FollowElastic and secure virtual cloud servers to cater all your cloud hosting needs.
Learn MoreMore Posts by Alibaba Clouder