Accreditation Bodies
Accreditation Bodies
Accreditation Bodies
Supercharge your career with our Multi-Cloud Engineer Bootcamp
KNOW MOREChef is a DevOps tool that uses infrastructure-as-code principles to automate, streamline, and enhance the reliability and scalability of IT operations. This tool empowers teams to efficiently manage and deploy resources using code instead of manual processes, reducing errors and downtime while increasing agility and speed. The following Chef interview questions and answers cover a wide range of basic-level topics associated with Chef, ones as the architecture of Chef, what Chef Supermarket and its different search indexes are, the occurrences in Chef Client run and many more. Meant for freshers, intermediate and experts at the same time, these top Chef interview questions with answers are divided into different categories to suit different levels of proficiency. Rest assured, going through these Chef interview question-answer sets will help you realize your dream to either be a Chef Developer, Full Stack engineer, or other top profiles. Practicing these questions will help you prepare better for your next Chef interview.
Filter By
Clear all
Chef architecture has three main components, Chef server, Chef node, and Chef workstation. At the workstation, code for provisioning and managing the infrastructure is created and tested. This code is implemented as recipes and a collection of recipes is known as a cookbook. Once the cookbook is ready, it is pushed to the Chef server from the workstation. We use the “knife” command-line tool or Berkshelf” to upload the cookbook. Chef Server typically acts as a hub for the infrastructure code. Chef node could be any system that is managed by Chef. It could be an actual or virtual or cloud machine.
Chef nodes communicate with the Chef server using an application called “chef-client”.Chef architecture works on pull configuration that means we don’t have to perform any actions on the Chef server to push the configurations to Chef nodes.“The chef-client” pulls down all the data needed for the Chef node to meet the desired criteria. This is also referred to as Chef run. During Chef run, a tool called OHAI collects the current status of the attributes of the node.
Chef:
Puppet:
Ansible:
Test Kitchen is an in-built Chef tool to test your recipes in a sandbox environment before moving it to production. We know that Chef does the provisioning and managing of infrastructure through code. A defect in the code can even change the production environment so we need an isolated environment where we can test our infrastructure code without worrying about the after-effects and the Test kitchen provides this. The test kitchen also helps us to test our infrastructure code on any platform by creating an instance with the respective OS. System tests using InSpec is often performed using Test kitchen as it helps us to test all actions in a sandbox environment. For eg: installation of the “Apache “ server on a Windows system is tested in Test kitchen by actually installing it on a provisioned Windows system.
.kitchen.yml created while generating a cookbook is the configuration file for the Test Kitchen. The test kitchen creates a sandbox environment using vagrant or docker. We can create multiple kitchen instances using a single .kitchen.yml file. The Test Kitchen is now often used in the CI pipeline of the applications to run the tests faster.
Chef Supermarket is a repository for cookbooks shared publicly. It’s a repository similar to GitHub. We can have two types of supermarket, private and other public. Public Chef Supermarket is hosted by Chef Software. We can find many general cookbooks like for eg: Nginx in public Chef supermarket. If any of the publicly shared cookbooks meet our requirements we can use them from the supermarket. We often come across situations where we need to modify the behavior of community cookbooks to achieve our requirements. This could be done by creating wrappers. So Chef supermarket is a central repository where one can share, download or collaborate on cookbooks.
Many companies prefer to create a private supermarket to share their company-specific cookbooks internally. Organisations whose cookbooks have security-related data prefer to only use private Chef Supermarket. They install a private supermarket by using “supermarket-omnibus-cookbook” available in Chef public supermarket. Retrieval of a cookbook in a private supermarket is faster compared to the public supermarket as we have fewer cookbooks to search from and due to its proximity.
Chef Client Run (CCR) is performed on each node by following several steps to ensure that the Chef node reaches its desired state. The different steps include
The “kitchen test” command is used to fully test the cookbooks in a CI/CD pipeline and is an elaborate process consisting of creating a new instance, converging it, verifying and then destroying the instance. Since this is an elaborate process it is not suited to be used in the development phase of a cookbook. "kitchen converge" and "kitchen verify" commands are more useful for the cookbook development phase.
“Kitchen converge” applies the cookbook to the existing sandbox environment. It will install the chef-client, load the cookbooks and other necessary files and goes ahead with the first Chef client run using kitchen.yml attributes. “Kitchen converge” has two types of return codes. A zero denotes success and a non zero value denotes failure at any step. If “kitchen converge” fails, try to delete the kitchen instance with “kitchen destroy” command and then run “kitchen converge” once again.
“Kitchen verify” helps in validating the state of the kitchen instance against test suites specified in .kitchen.yml file. Often "kitchen converge" and "kitchen verify" are frequently used to develop infrastructure code using Test Driven Development.
“metadata.rb” file is at the top level of every cookbook directory and gets created as soon as a cookbook is created. (For JAVA programmers the concept is similar to a constructor getting created when an object is created!) It specifies all the dependencies required to correctly deploy a cookbook to its nodes. The Chef server compiles this metadata.rb file into metadata.json file and stores it. We can edit the metadata in the metadata.rb file and should be recompiled every time by the Chef server for the changes to be implemented. Metadata.rb file is compiled when
Metadata.rb files have entries under ‘depends’ keyword which specifies the different dependencies required to successfully deploy the cookbook in a specific node. If these dependencies are not given properly we may often face errors while deploying cookbooks and Chef nodes would not be configured as expected. Apart from "depends", we have other details given in the metadata.rb file like license, version, gem, etc. which can be parametrized using different operators (=,>=, >, etc)
From Chef 0.10, a ‘chefignore’ file is used to ignore unwanted temporary files like swap files, version control files, build data files, etc while uploading to the Chef server. This file is could be available at any of the subfolders of your cookbook repository. This file helps us to stop uploading unwanted files or confidential files to Chef Server.
For eg: while using Vim editor, it leaves behind swap files. These are of no use in reusing the uploaded cookbooks. These will get uploaded into the Chef Server unless specified in the chefignore file. The following entry in the chefignore file stops all swap files created by Vim editor being uploaded. This helps us to stop accidentally uploading these swap files which is not related to the cookbook and not required for the correct functioning of the cookbook.
# vim *.sw[a-z]
Chefignore file can use *,** and? wildcards to specify the ignore patterns in chefignore file. The pattern matching in the file is concerning
The different search indexes for node data in Chef Server are as follows:-
Recipes are the basic configuration element in any organisations. Its a programmatic representation of the desired state of the nodes. Usually written in ruby with Chef Domain Specific Language (DSL), these specify all the standards (policies) or updates that the nodes should follow. Recipes are often a collection of resources that are the building blocks of the infrastructure of any organisations.
Cookbooks are a collection of recipes. Apart from recipes, cookbooks contain other elements like metadata, attributes, libraries, resources, templates, and tests which helps the nodes to achieve their desired state. Cookbooks can be created by Chef commands or by the Chef command-line tool called Knife. The cookbooks are the fundamental units of chefs and are uploaded to the Chef Servers and then read and deployed by the Chef Clients at the nodes. Cookbooks are standalone entities that could be transferred easily between the Chef server and node. It typically implements a scenario of infrastructure and has everything required for the scenario. Cookbooks could be version controlled and hence help the development team to collaborate and share cookbooks.
The “knife upload” command is used to upload the cookbooks to the Chef server. It does not help in managing the cookbook dependencies. So knife command is not chosen for very complicated and large cookbooks with dependencies that in turn might be dependent on others and so on. For eg: Assume that a cookbook called “my-app” depends on community cookbook “nginx” which in turn depends on another community cookbook “ohai”. When we try to upload “my-app” to Chef Server using the “knife upload” command, we have to make sure all other dependent cookbooks are uploaded manually to Chef Server. This problem is solved using “berkshelf upload”
Berkshelf command is similar to knife command and helps to upload cookbooks to Chef Server. But it also helps in the management of cookbooks outside of Chef repository. This is quite useful in case of large and complex cookbooks with lots of dependencies. “berkshelf upload” will upload all dependent cookbooks to the Chef server automatically. All the dependent cookbooks are fetched using the “berks install” command of the Berkshelf tool.
InSpec is an in-built testing framework for testing and auditing infrastructure in Chef. A sample InSpec test to verify whether “Nginx” server is installed and running in a system could be written as follows:
```control 'Nginx-install-1.0' do title 'Check if nginx is installed' describe package 'nginx' do it { should be_installed } end end control 'Nginx should be running' do describe service 'nginx' do it { should be_running } end end```
Main components of InSpec tests are:
Chef Client run could be performed in the following modes:
We can update the Chef run lists with the below two options:
For eg:
```knife node run_list add <NODE_NAME> <RUN_LIST_ITEM> (options)``` commands could be used to add a recipe or a role in the run list of a node.
Similarly
```knife node run_list remove <NODE_NAME> <RUN_LIST_ITEM> (options)``` command could be used to remove from the run list.
We can also specify the run list for a node while bootstrapping the node using the “knife bootstrap” command.
Unit tests are easy to run simpler tests used to test a single unit or component of the infrastructure. Chef uses ChefSpec, an in-built testing framework to write unit tests for the infrastructure. In the infrastructure point of view unit tests are verified on the resource collection created during the Chef Client run and not by actually configuring the node.
For eg: If we want to write a unit test to verify if the “Apache” package is installed, no actual installation of the Apache server is tested but just verifies if the package “Apache” is added to the resource collection list. Resource collection will have a list of all actions that will be performed in the actual Chef Client run.
Integration tests in Chef's perspective are system tests where tests are performed by provisioning a new system and configuring the system to our requirements. This takes a lot of time as we have to perform the actual configuration of the provisioned system. System tests are also a costly affair compared to unit tests as we need to provision a new system exclusively for testing purposes.
“file” resources in Chef are used to manage files in a Chef node during a chef-client run . A sample file resource is as follows:
```file ‘/tmp/index.html’ do content 'Hello World' end```
“file” resource has a name field that defines the resource block. In the above example ‘/tmp/index.html’ defines the name of the file which is managed by Chef with the path. Various actions performed by file resource is as follows:
“cookbook_file” resource is used to copy files from the “files” folder of the Chef cookbook to a path in Chef node during a chef-client run. Sample “cookbook_file” is specified as below:
```cookbook_file '/var/index.php' do source 'index.php' action :create end```
Here file “index.php” from “files” folder in the cookbook is copied to “index.php” file in “/var” path in Chef node. If file not present it’s created at the path.If the file is present and if the checksum of the “index.php” file matches the “index.php” file in the cookbook of Chef Server, no file transfer is performed.
“template” resources are used to dynamically generate static files from an embedded Ruby template placed in the “templates” folder of a cookbook. For eg:
```template '/etc/motd' do source 'motd.erb' end```
“/etc/motd” is the location at which a new file is created on Chef node during a chef-client run based on the template file “motd.erb” placed in the “templates” folder of the cookbook.A template file may contain Ruby statements and expressions unlike in “file” resource or “cookbook_file” resource.
Attributes define a node! In other words, it’s a characteristic of your node when it runs in a specific role under a specific environment against a specific cookbook or recipe. Hence attributes can be found in all these Chef components such as roles, environment, cookbooks and even as a separate set called “attribute files”. The different types of attributes available in the chef are:-
In the Chef architecture, we have multiple Chef nodes managed by a Chef Server. Hence care must be taken to authenticate a Chef node with Chef Server. No stranger nodes should be able to send requests to Chef Server. So we use the “knife ssl fetch “ command to copy the self-signed SSL certificate of Chef Server to the trusted certificates directory in a respective node or a Chef Workstation. Only nodes or workstations with a valid SSL certificate could communicate with Chef Server without any errors. The URL for Chef Server is often specified in “client.rb” file in Chef node and “knife.rb” file in Chef Workstation. We can override this setting by supplying the URL of any Chef Server when the “knife ssl check” and “knife ssl fetch” command is run
“Knife ssl check” command is used to verify if the SSL certificate has a valid X.509 certificate property. “knife ssl check” and “knife ssl fetch” could be used to troubleshoot communication errors with Chef Server. This process is not valid for verifying communication with Hosted Chef Servers.
execute resources in Chef is used to execute a single command. All commands executed via execute resources are not idempotent and are specific to the environment in which it’s run. We need to use guards like “not_if”, “only_if” to make the execution of the resource idempotent. During a Chef Client run, guards property verifies the state of the Chef node. "execute" resources could be run alone or in combination with other in-built Chef resources like templates, etc. "execute" resources could be used when we need to reuse existing shell scripts for infrastructure configurations. We need to specify the command to run the shell script in "execute" resource block.
For eg:
```execute 'apache_test' do command '/usr/apachectl configtest' end```
“apache_test” is the name provided for the "execute" resource block. The actual command run is “/usr/apachectl configtest”.
Execute resource could have only two actions, nothing and run. If the action specified is "run", the command provided is executed. If the action specified is nothing, the command provided in the "execute" block is prohibited from running. script resource is often confused with execute resource. Script resource is used to execute a script using an interpreter provided like bash etc
Chef nodes in your infrastructure may perform different roles at different times. For eg: Few of the Chef nodes would be web servers and one would be a load balancer. Grouping of the nodes into web servers and load balancer could be achieved in Chef using “roles” feature. The roles are defined through the role attributes. You can assign roles to your identical servers and all of them can go ahead and run the same run list mapped to the corresponding role. This helps in avoiding the process of running run lists manually on each node each time when you have many nodes performing the same function.
For configuring a new role for our node, we can make use of Knife commands. As a prerequisite, any previous roles or recipes on the run list can be removed using the “knife node run-list remove” command and then we can go ahead and add our newly added role using the “knife node run-list add role” command. The role attributes could only be defined as either ‘default’ or ‘override’ attributes. When a Chef Client run happens, the role attributes are matched against the attributes present on the node and if it takes precedence over default attributes, new settings are applied.
Bootstrap is the process by which the Chef Client is installed on the Chef nodes. Chef nodes could be physical, virtual or cloud machine. The bootstrap process can be done in two ways:
The “knife bootstrap” command is issued from the Chef workstation. The command first creates an SSH connection with the node then installs the Chef Client along with all its dependencies on the node. This command also generates keys and register the node with Chef Server. In earlier versions of Chef Client, "ORGANIZATION-validator.pem" file was used to authenticate the Chef node with the Chef Server during the first Chef Client run. Starting from Chef Client 12.1, "USER.pem" file could be used to authenticate the new Chef node. This process is also known as “validatorless bootstrap”.
We need to login to the Chef node and manually install the chef-client. Once it’s installed we need to manually set up the connection with the Chef Server.
Unattended Installs are often done on Chef nodes created in AWS Auto Scaling, AWS CloudFormation, Rackspace Auto Scale, and PXE. Chef Client is installed without SSH connection on the Chef nodes.
Security is an important feature in infrastructure management, in Chef this could be achieved through data bags. While preparing recipes for setting the different nodes we might need to provide some sensitive data as well for example like authorization credentials. It is not a good practice to hard code them as this may lead to many security risks. It is here where we can make use of data bags. Data bags are places where we can save these important data, the data gets stored in JSON format (Key-value pairs).
Data bags are indexed hence can be called whenever required by the recipes or cookbooks through a search. The data bags are encrypted and hence the contents of the data bags can be accessed only by having a decrypting key, this is how data bags give security to the chef infrastructure. Other than encryption strategies, a Chef Data Bag can be secured using a ‘Chef Vault’. Data bags can be created through the commands in the knife utility tool or manually. Data bags could be considered as a method to store global data shared across nodes.
Setting up environments is an important part of infrastructure management. We know that for the successful development of any product we need different environments like a development environment, testing environment, production environment, etc. The concept of environments in Chef is the extrapolation of the same. We at times want our Chef nodes to converge to a testing environment or a production environment configurations. Hence we can have a particular configuration for a testing environment and different configuration for the production environment. This switching of node behaviour is achieved through Chef environment settings. Environments help administrators to easily identify the stage where the particular node is a part of.
If we don’t declare any environments the Chef assumes the nodes to be in “_default” environment. Minimum one environment exists in an organisation. Environment attributes have higher precedence than default attributes of a node. Environment data could be stored in Ruby format or JSON format. An environment could be created as follows:
Chef Software hosts a repository for general-purpose community cookbooks called Chef Supermarket. Hence Chef users can use these designed and tested cookbooks wherever possible which in turn will reduce the infrastructure development time. But often we come across situations where we need to tweak the community cookbooks for our requirement i.e where wrapper cookbooks are created. Wrapper cookbooks are similar to normal cookbooks but they use recipes from other cookbooks also.One another scenario where wrapper cookbooks are created is where you have a large number of baseline cookbooks and we need to organise them for maintainability.
We create wrapper cookbooks and put in external recipes from other cookbooks for our use. This could be achieved by modifying
Wrapper classes can be further customized to your needs through some simple attribute changes. Attribute definitions and run lists of the nodes could also be version controlled using wrapper cookbooks.
chef-repo in your Chef Workstation is a directory that holds all details about cookbooks, environments, roles, and data bags.chef-repo is like source code and need to be synchronized with version control system like Git.chef-repo has following directories and files
Chef-apply is an in-built utility in Chef development kit. It helps to run a recipe from the command line. The basic syntax for chef-apply is as follows:
During Chef Server creation, you are asked to download Starter kit to Chef Workstation. After downloading, unzip the starter kit and move it to your desired path. Every Time the Starter Kit is downloaded, a new key pair is created and resets the older one. Starter Kit has all the configuration details for communicating with Chef Server. It helps us to create a folder structure for developing cookbooks. Main directories present in Starter Kit would be as follows:
Whenever a cookbook is modified, the new version details of the cookbook is updated in “metadata.rb” file and then uploaded to Chef Server using knife upload or berkshelf upload. There are 3 ways in which the new cookbook would be applied to the desired Chef nodes.
Handlers are used to solve different situations that arise during a Chef Client run. There are 3 types of handlers in Chef.
Exception and report handlers provide a wide range of information about the Chef Client run and these data could be used for analysis across the organizations.
Ohai in Chef is used to detect Chef node attributes and these are provided to chef-client during the Chef Client run. Ohai collects details about various platforms, network data, memory data, CPU data, kernel data and other configuration details. All these attributes collected are automatic attributes that are not changed even after Chef Client run. Automatic attributes are having higher precedence overall default, override, force-default and normal attributes. Ohai gets installed with the Chef Client installation.
The ohai resource is available in Chef to reload the configuration of a node. These are often used to refer back system attributes that are changed by a recipe like a recipe that creates a new user during a Chef Client run. The syntax is as follows :
ohai 'name' do plugin String action Symbol # defaults to reload if not specified end
where:
Foodcritic is an open-source tool used to detect common problems in our cookbooks like style, syntaxes, best practices, correctness etc. Foodcritic validates the Ruby code written in cookbook against several rules and creates a list of violations without running a Chef Client run. List of rules is available in Foodcritic website.
A foodcritic is often run from chef-repo with the name of the cookbook whose correctness we are going to verify. The correctness of the intention of the recipes in the cookbook is not checked instead the structure and syntax of the cookbook are checked. Whenever a Foodcritic detects violation it doesn't typically mean a change of code. For eg: Assume that rule number “FC003” defines a scenario where recipe uses a search method to get relevant data from the Chef Server. The rule suggests that an error may occur in the cookbook when the Chef Server is unavailable. We only bother to adopt this rule only if chef-solo is a part of our project workflow as chef-solo doesn’t work with Chef Server.
Food critic could also be used with Continuous Integration servers like Jenkins and Travis thus enabling automated checking within the delivery pipeline of our project.
ChefSpec is an in-built testing framework for testing resources and recipes. It’s a part of Chef Development Kit. Usually, unit tests are written in ChefSpec and is an extension of Behavior Driven Development framework called RSpec for Ruby.
A sample unit test to check if “Nginx” package is installed or not is written as follows:
describe 'nginx::default' do context 'When all attributes are default, on Ubuntu 16.04' do let(:chef_run) do runner = ChefSpec::ServerRunner.new(platform: 'ubuntu', version: '16.04') runner.converge(described_recipe) end it 'install a package' do expect(chef_run).to install_package('nginx') end end
where
Custom resources in Chef are add on resources transported as a pat of cookbooks and used by Chef Client. These are reusable in the same way as pre-defined resources in Chef. Custom resources are kept as a separate Ruby file in the resources folder of a cookbook. For eg: Assume that we need to create a custom resource called “website” that make use of in-built resources of Chef like file, package and service resources.
“website.rb “ file looks as follows:
property :home, String, default: '<h1>Welcome!</h1>' action: create do package 'nginx' service 'nginx' do action [:enable, :start] end file '/var/www/html/index.html' do content new_res.homepage end end action :delete do package 'nginx' do action :delete end end
Where
The website resource is named after the cookbook name and the file name in the resources folder. Hence if the name of our cookbook is “sample” our custom resource is defined as “sample_website” and could be used in the cookbook as follows:
sample_website 'nginx' do home '<h1>Welcome to the Sample website!</h1>' end
“Knife supermarket download” command is used to download the cookbook available in Chef Supermarket be it private or public supermarket.
The cookbooks downloaded are in the form of tar.gz files and are downloaded to the current working directory. If the specified cookbook is deprecated in the Chef Supermarket the user is notified the same and provides the details of the most recent version of the non-deprecated cookbook. For eg :
knife supermarket download httpd
downloads “httpd “cookbook from Chef Supermarket.
“knife supermarket install “ command is used to communicate with cookbooks in public or private Chef Supermarket. The downloaded cookbooks are installed in the local git repository unlike in the case of “knife supermarket download” command.“knife supermarket install “ command does the following steps
Hence this command allows updated upstream versions to be used without losing the local modifications done to the cookbook.
Chef Node is any physical, virtual or cloud machine configured by Chef Client and managed by Chef Server. A “chef-client run” is used to describe a series of steps the chef-client performs when it is configuring a node. During a chef-client run, the specified node is registered with Chef Server. This is done to avoid unwanted requests to be sent to Chef Server from chef-clients. Every request initiated by chef-client is authenticated using Chef Server API and a private key stored in “/etc/chef/client.pem” file in Chef Node.
During the first chef-client run on any node, the node won’t have the private key hence private key specified in the chef-validator placed in “/etc/chef/validation.pem” file is used. If chef-validator is unable to send an authenticated request to Chef Server the chef-client run will fail. After the node gets registered with the Chef Server chef-client attains a “client.pem” private key which will be used for all future authentication requests to the Chef server.chef-validator is not used after the initial chef-client run and hence could be deleted.
Best practices in developing a cookbook are to use
These techniques help us to reduce the debugging effort greatly.
Main debugging techniques used to detect defects in recipes and chef-client runs are
Run Chef Client with an empty run list. This helps us to make sure that the chef-client run failure is not due to the recipes added in the run list. We are also now sure that the failure is due to the configuration settings of Chef Client. chef-client run failure could also occur due to permission issues of the user at Chef Server and also on the node where Chef Client is run.
A built-in verbose logging of knife with “-v” option could be used to log messages
Chef Client could be run with verbose logging by using the “-l” option. “-L” option could also be used to specify the location of the log file.
log resource could be used to log the debug messages while running the Chef Client. This resource is also built into resource collection and run during the convergence phase. If we want to add log entries that are not added to the resource collection, use Chef:: Log. A sample log resource looks as below:
log 'mtr' do message 'A info message added.' level :info end
Where
Test-Driven Development is a DevOps practise where code is developed just to make a failing test pass. It follows a red, green, refactors cycle. In the case of Infrastructure point of view, we first write a test and see it fail. Then write the code to make the test pass and then refactor if required. TDD helps to create high quality, simpler code with high modularity.
In Chef, Test Kitchen helps us to perform TDD. We first write the InSpec test and run “kitchen verify” command to perform the test. If the test fails, enough code is written to make the test pass. We converge the node to the desired state using “kitchen converge” command. Then again “kitchen verify” command is run to verify if the test has passed. Then the code is refactored if required when all tests have passed. In places where CI/CD is used, we can use “kitchen test “ command to invoke creation of kitchen instance, converging and verifying and at last destroyed the kitchen instance. Hence helping us to detect the defects very easily and in the early stages of project development.
A cookbook is versioned whenever there is a third party component change, a bug fix, the addition of new features or improvements to existing cookbook. This helps us to easily organise the cookbook and let us know which version of the cookbook has what functionalities. This also helps us to specifically update a version of the cookbook to Chef Server and use it for chef-client runs.
A cookbook version is in the format “a.b.c” where a, b, c are decimal numbers. “a”, “b”, “c” represents major, minor and patch versions respectively. For eg: 1.1.2 version represents major and minor release version “1” with patch version “2”.Versions like “1.2a.3” or “1.2.3.4” or “3” are not allowed.
A version restriction could be attained by combining a cookbook version with an operator. Following operators are used
Cookbook versions are specified in the “metadata.rb” file located at the top of our cookbook.
include_recipe method is used to include one or more recipes from cookbooks. It might be recipes from the same cookbook or dependent cookbooks. The syntax for the include_recipe method is as follows:
include_recipe <Recipe name with the cookbook>
For eg :
include_recipe 'apache2::mod_ssl'
includes all resources from the “mod_ssl.rb” file in “apache2” cookbook to our current recipe where the “include_recipe” directive is specified. If same recipes are included multiple times using “include_recipe” directive method, only the first is included and rest is neglected.”include_recipe” directive is considered better practice than specifying the recipe in the run list especially when one cookbook depends on another cookbook. This also lessens the burdens of running the dependent cookbooks first by specifying it first in the run list of every Chef node.
In the case of wrapper cookbooks “include_recipe” directive is used to include functionalities from the dependent cookbooks. If it’s not specified but the dependent cookbooks are specified in the depends section of “metadata.rb” file, an error occurs.
Libraries store arbitrary Ruby code that could be reused across the recipes within any cookbook that depends on the library. This is often located in the library folder of our cookbooks. First and the foremost usage of libraries are to provide helper methods that reduce the code duplication and also provide a mechanism to hide the implementation logic in the recipes. Libraries get loaded first when the Chef loads our cookbooks.It make use of “ load_libraries_from_cookbook” method from the “Chef::RunContext::CookbookCompiler” class. Typical use cases of libraries are
Policyfiles are used to combine the advantages of roles and environment with Berkshelf.In usual Chef Workflow, the versions and the locations of cookbooks being used by a Chef Client are updated in “metadata.rb” file and “Berksfile”. Often this is a tedious task and a small error in these files make Chef Client apply the wrong cookbook and converged node would not acquire the required state. These problems could be solved by using a single document called Policyfiles to get the specific cookbook revisions and recipes that Chef Infra Client would apply. Policyfiles are applied on a group of nodes, cookbooks or settings. The syntax for a Policyfile.rb file is as follows:
name "name" run_list "ITEM", "ITEM", ... default_source :SOURCE_TYPE, *args cookbook "NAME" [, "VERSION_CONSTRAINT"] [, SOURCE_OPTIONS]
where
Chef shell is an interactive tool to work with resources. It helps to do REPL with the resources.chef-shell provides an easy method to test resources interactively rather than uploading our cookbook to Chef Server and applying it on Chef nodes. Breakpoints could be added on to the recipe execution using chef-shell.chef-shell could be used in three modes
Berkshelf is the dependency manager that comes with the Chef Development Kit. Whenever you create a cookbook say for eg with “chef generate cookbook” command a file called Berksfile is created on top of the cookbook directory. This file contains the source path for all cookbooks. Assume that you created a new cookbook called “my-app” which depends on another community cookbook “nginx” from public Chef Supermarket. The typical steps we follow are:
“chef_gem” and “gem_package” resources are used to install Ruby gems. Every system where Chef Client is installed has two versions of Ruby running. One is a system-wide instance of Ruby and the other is the one available only with Chef Client. “chef_gem” resource is used to install Ruby into Chef Client instance of Ruby and “gem_package” resource to install Ruby into a system-wide instance.
gem_package resource has a property called “gem_binary” property that is used by Chef Client to detect the environment settings and then install the gems. "chef_gem" resource is having all properties and options as that of “gem_package” resource except the “gem_binary” property.”chef_gem” resource always uses “CurrentGemEnvironment” where the Chef Client is running.
“chef_gem” resource has additional functions of
The attributes that should not be saved by the node is called Blacklisted attributes. These are defined in the client.rb file. Attributes are blacklisted based on attribute types. “automatic_attribute_blacklist “ defines a hash that blacklists automatic attributes. Similarly “default_attribute_blacklist”, “normal_attribute_blacklist” and “override_attribute_blacklist” are hashes that blacklist default attributes, normal attributes and override attributes respectively. The best practice is to use “automatic_attribute_blacklist “ as automatic attributes generate most data after an Ohai run. For eg:
automatic_attribute_blacklist ['filesystem']
could be used to blacklist only ‘filesystem’ attributes in the below sample attribute data
{ "filesystem" => { "/dev/disk0s2" => { "size" => "10mb" } } }
All other automatic attributes are saved by the node.
The attributes that are needed to be saved by a node are called Whitelist attributes.
These are also defined in the client.rb file. Similar to blacklist attributes, attributes are also whitelisted using attribute type.”automatic_attribute_whitelist”, “default_attribute_whitelist”, “normal_attribute_whitelist”, “ override_attribute_whitelist” are hashes used to whitelist automatic, default, normal and override attributes respectively. For eg:
automatic_attribute_whitelist ['network/interfaces/']
could be used to whitelist only network attributes among the automatic attributes generated like below:
{ "network" => { "interfaces" => { "eth0" => {...}, "eth1" => {...}, } } }
chef-solo is a command where Chef Client is run in a way that it doesn’t require Chef Server to get the required cookbooks.chef-solo make use of the local mode of the chef-client run. It doesn’t require authorisation as in the case of Chef Servers. It also doesn’t provide a centralised distribution of cookbooks or centralised API to interact with infrastructure components. Cookbooks could be loaded from two different locations i.e from a local directory or a URL where the tar.gz archive is present. In chef-solo, the node objects are stored in the form of JSON files in a local disk rather than as node objects in Chef Server. For eg:
chef-solo -c ~/solo.rb -j ~/node.json -r http://www.sample.com/chef-solo.tar.gz
runs chef-solo with solo.rb configuration file using node.json file and retrieves cookbook from the http://www.sample.com/chef-solo.tar.gz URL.
The basic workflow for chef-solo is as follows:
Ohai framework provides a mechanism to create our own customised plugins to get more details about a Chef Node. For eg: if we want to find out if a Chef node is a virtual machine or not, no Ohai plugin gathers this information so we need to create a plugin for the same. Ohai makes uses of Ruby-based DSL to create plugins. Ohai plugins are usually kept in “lib/ohai/plugins” directory in the repository. A sample Ohai plugin will look like below:
Ohai.plugin(:Sample) do provides "level" collect_data do level 100 end end
where
Ohai plugins are tested in IRB Ruby shell. This helps us to run plugins without performing actual Chef Client runs or configuring nodes. After testing is complete and we need to run the plugins we have to specify the path of the new plugin by specifying Ohai::Config[:plugin_path] << /location/of/plugins line in client.rb or solo.rb file. This helps Ohai to load the plugins correctly
kitchen.yml file is the configuration file for the Test Kitchen. All details needed to create a sandbox environment for testing our infrastructure using Chef is included in .kitchen.yml file
Syntax of a .kitchen.yml file is as follows:
The basic structure of a .kitchen.yml file is as follows:
driver: name: driver_name provisioner: name: provisioner_name verifier: name: verifier_name transport: name: transport_name platforms: - name: platform-version driver: name: driver_name suites: - name: suite_name run_list: - recipe[cookbook_name::recipe_name]
where
Cookstyle is an in-built linting tool that checks for
Cookstyle is based on RuboCop Ruby linting tool.
Cookstyle is run from the command line against a cookbook and verifies all the Ruby files in the cookbook. Cookstyle is run as cookstyle <cookbook path> and the output is provided via standard output on the terminal.
The output gives us information about the number of files present and verified, defects detected and place of defects. The result of the verification of the files is shown below:
Autocorrection facility is available for files with cookstyle warnings but care must be taken not to alter the functionality of the code after using auto-correction. Default settings in the cookstyle could be overridden by .rubocop.yml file in a cookbook.
Frozen cookbooks are those cookbooks which cannot be re-imported or modified. Hence the frozen cookbooks would not even be accidentally modified. For eg: This method helps us to protect our production environments from being modified while testing changes made to the development infrastructure. We can freeze a cookbook as follows:
Chef architecture has three main components, Chef server, Chef node, and Chef workstation. At the workstation, code for provisioning and managing the infrastructure is created and tested. This code is implemented as recipes and a collection of recipes is known as a cookbook. Once the cookbook is ready, it is pushed to the Chef server from the workstation. We use the “knife” command-line tool or Berkshelf” to upload the cookbook. Chef Server typically acts as a hub for the infrastructure code. Chef node could be any system that is managed by Chef. It could be an actual or virtual or cloud machine.
Chef nodes communicate with the Chef server using an application called “chef-client”.Chef architecture works on pull configuration that means we don’t have to perform any actions on the Chef server to push the configurations to Chef nodes.“The chef-client” pulls down all the data needed for the Chef node to meet the desired criteria. This is also referred to as Chef run. During Chef run, a tool called OHAI collects the current status of the attributes of the node.
Chef:
Puppet:
Ansible:
Test Kitchen is an in-built Chef tool to test your recipes in a sandbox environment before moving it to production. We know that Chef does the provisioning and managing of infrastructure through code. A defect in the code can even change the production environment so we need an isolated environment where we can test our infrastructure code without worrying about the after-effects and the Test kitchen provides this. The test kitchen also helps us to test our infrastructure code on any platform by creating an instance with the respective OS. System tests using InSpec is often performed using Test kitchen as it helps us to test all actions in a sandbox environment. For eg: installation of the “Apache “ server on a Windows system is tested in Test kitchen by actually installing it on a provisioned Windows system.
.kitchen.yml created while generating a cookbook is the configuration file for the Test Kitchen. The test kitchen creates a sandbox environment using vagrant or docker. We can create multiple kitchen instances using a single .kitchen.yml file. The Test Kitchen is now often used in the CI pipeline of the applications to run the tests faster.
Chef Supermarket is a repository for cookbooks shared publicly. It’s a repository similar to GitHub. We can have two types of supermarket, private and other public. Public Chef Supermarket is hosted by Chef Software. We can find many general cookbooks like for eg: Nginx in public Chef supermarket. If any of the publicly shared cookbooks meet our requirements we can use them from the supermarket. We often come across situations where we need to modify the behavior of community cookbooks to achieve our requirements. This could be done by creating wrappers. So Chef supermarket is a central repository where one can share, download or collaborate on cookbooks.
Many companies prefer to create a private supermarket to share their company-specific cookbooks internally. Organisations whose cookbooks have security-related data prefer to only use private Chef Supermarket. They install a private supermarket by using “supermarket-omnibus-cookbook” available in Chef public supermarket. Retrieval of a cookbook in a private supermarket is faster compared to the public supermarket as we have fewer cookbooks to search from and due to its proximity.
Chef Client Run (CCR) is performed on each node by following several steps to ensure that the Chef node reaches its desired state. The different steps include
The “kitchen test” command is used to fully test the cookbooks in a CI/CD pipeline and is an elaborate process consisting of creating a new instance, converging it, verifying and then destroying the instance. Since this is an elaborate process it is not suited to be used in the development phase of a cookbook. "kitchen converge" and "kitchen verify" commands are more useful for the cookbook development phase.
“Kitchen converge” applies the cookbook to the existing sandbox environment. It will install the chef-client, load the cookbooks and other necessary files and goes ahead with the first Chef client run using kitchen.yml attributes. “Kitchen converge” has two types of return codes. A zero denotes success and a non zero value denotes failure at any step. If “kitchen converge” fails, try to delete the kitchen instance with “kitchen destroy” command and then run “kitchen converge” once again.
“Kitchen verify” helps in validating the state of the kitchen instance against test suites specified in .kitchen.yml file. Often "kitchen converge" and "kitchen verify" are frequently used to develop infrastructure code using Test Driven Development.
“metadata.rb” file is at the top level of every cookbook directory and gets created as soon as a cookbook is created. (For JAVA programmers the concept is similar to a constructor getting created when an object is created!) It specifies all the dependencies required to correctly deploy a cookbook to its nodes. The Chef server compiles this metadata.rb file into metadata.json file and stores it. We can edit the metadata in the metadata.rb file and should be recompiled every time by the Chef server for the changes to be implemented. Metadata.rb file is compiled when
Metadata.rb files have entries under ‘depends’ keyword which specifies the different dependencies required to successfully deploy the cookbook in a specific node. If these dependencies are not given properly we may often face errors while deploying cookbooks and Chef nodes would not be configured as expected. Apart from "depends", we have other details given in the metadata.rb file like license, version, gem, etc. which can be parametrized using different operators (=,>=, >, etc)
From Chef 0.10, a ‘chefignore’ file is used to ignore unwanted temporary files like swap files, version control files, build data files, etc while uploading to the Chef server. This file is could be available at any of the subfolders of your cookbook repository. This file helps us to stop uploading unwanted files or confidential files to Chef Server.
For eg: while using Vim editor, it leaves behind swap files. These are of no use in reusing the uploaded cookbooks. These will get uploaded into the Chef Server unless specified in the chefignore file. The following entry in the chefignore file stops all swap files created by Vim editor being uploaded. This helps us to stop accidentally uploading these swap files which is not related to the cookbook and not required for the correct functioning of the cookbook.
# vim *.sw[a-z]
Chefignore file can use *,** and? wildcards to specify the ignore patterns in chefignore file. The pattern matching in the file is concerning
The different search indexes for node data in Chef Server are as follows:-
Recipes are the basic configuration element in any organisations. Its a programmatic representation of the desired state of the nodes. Usually written in ruby with Chef Domain Specific Language (DSL), these specify all the standards (policies) or updates that the nodes should follow. Recipes are often a collection of resources that are the building blocks of the infrastructure of any organisations.
Cookbooks are a collection of recipes. Apart from recipes, cookbooks contain other elements like metadata, attributes, libraries, resources, templates, and tests which helps the nodes to achieve their desired state. Cookbooks can be created by Chef commands or by the Chef command-line tool called Knife. The cookbooks are the fundamental units of chefs and are uploaded to the Chef Servers and then read and deployed by the Chef Clients at the nodes. Cookbooks are standalone entities that could be transferred easily between the Chef server and node. It typically implements a scenario of infrastructure and has everything required for the scenario. Cookbooks could be version controlled and hence help the development team to collaborate and share cookbooks.
The “knife upload” command is used to upload the cookbooks to the Chef server. It does not help in managing the cookbook dependencies. So knife command is not chosen for very complicated and large cookbooks with dependencies that in turn might be dependent on others and so on. For eg: Assume that a cookbook called “my-app” depends on community cookbook “nginx” which in turn depends on another community cookbook “ohai”. When we try to upload “my-app” to Chef Server using the “knife upload” command, we have to make sure all other dependent cookbooks are uploaded manually to Chef Server. This problem is solved using “berkshelf upload”
Berkshelf command is similar to knife command and helps to upload cookbooks to Chef Server. But it also helps in the management of cookbooks outside of Chef repository. This is quite useful in case of large and complex cookbooks with lots of dependencies. “berkshelf upload” will upload all dependent cookbooks to the Chef server automatically. All the dependent cookbooks are fetched using the “berks install” command of the Berkshelf tool.
InSpec is an in-built testing framework for testing and auditing infrastructure in Chef. A sample InSpec test to verify whether “Nginx” server is installed and running in a system could be written as follows:
```control 'Nginx-install-1.0' do title 'Check if nginx is installed' describe package 'nginx' do it { should be_installed } end end control 'Nginx should be running' do describe service 'nginx' do it { should be_running } end end```
Main components of InSpec tests are:
Chef Client run could be performed in the following modes:
We can update the Chef run lists with the below two options:
For eg:
```knife node run_list add <NODE_NAME> <RUN_LIST_ITEM> (options)``` commands could be used to add a recipe or a role in the run list of a node.
Similarly
```knife node run_list remove <NODE_NAME> <RUN_LIST_ITEM> (options)``` command could be used to remove from the run list.
We can also specify the run list for a node while bootstrapping the node using the “knife bootstrap” command.
Unit tests are easy to run simpler tests used to test a single unit or component of the infrastructure. Chef uses ChefSpec, an in-built testing framework to write unit tests for the infrastructure. In the infrastructure point of view unit tests are verified on the resource collection created during the Chef Client run and not by actually configuring the node.
For eg: If we want to write a unit test to verify if the “Apache” package is installed, no actual installation of the Apache server is tested but just verifies if the package “Apache” is added to the resource collection list. Resource collection will have a list of all actions that will be performed in the actual Chef Client run.
Integration tests in Chef's perspective are system tests where tests are performed by provisioning a new system and configuring the system to our requirements. This takes a lot of time as we have to perform the actual configuration of the provisioned system. System tests are also a costly affair compared to unit tests as we need to provision a new system exclusively for testing purposes.
“file” resources in Chef are used to manage files in a Chef node during a chef-client run . A sample file resource is as follows:
```file ‘/tmp/index.html’ do content 'Hello World' end```
“file” resource has a name field that defines the resource block. In the above example ‘/tmp/index.html’ defines the name of the file which is managed by Chef with the path. Various actions performed by file resource is as follows:
“cookbook_file” resource is used to copy files from the “files” folder of the Chef cookbook to a path in Chef node during a chef-client run. Sample “cookbook_file” is specified as below:
```cookbook_file '/var/index.php' do source 'index.php' action :create end```
Here file “index.php” from “files” folder in the cookbook is copied to “index.php” file in “/var” path in Chef node. If file not present it’s created at the path.If the file is present and if the checksum of the “index.php” file matches the “index.php” file in the cookbook of Chef Server, no file transfer is performed.
“template” resources are used to dynamically generate static files from an embedded Ruby template placed in the “templates” folder of a cookbook. For eg:
```template '/etc/motd' do source 'motd.erb' end```
“/etc/motd” is the location at which a new file is created on Chef node during a chef-client run based on the template file “motd.erb” placed in the “templates” folder of the cookbook.A template file may contain Ruby statements and expressions unlike in “file” resource or “cookbook_file” resource.
Attributes define a node! In other words, it’s a characteristic of your node when it runs in a specific role under a specific environment against a specific cookbook or recipe. Hence attributes can be found in all these Chef components such as roles, environment, cookbooks and even as a separate set called “attribute files”. The different types of attributes available in the chef are:-
In the Chef architecture, we have multiple Chef nodes managed by a Chef Server. Hence care must be taken to authenticate a Chef node with Chef Server. No stranger nodes should be able to send requests to Chef Server. So we use the “knife ssl fetch “ command to copy the self-signed SSL certificate of Chef Server to the trusted certificates directory in a respective node or a Chef Workstation. Only nodes or workstations with a valid SSL certificate could communicate with Chef Server without any errors. The URL for Chef Server is often specified in “client.rb” file in Chef node and “knife.rb” file in Chef Workstation. We can override this setting by supplying the URL of any Chef Server when the “knife ssl check” and “knife ssl fetch” command is run
“Knife ssl check” command is used to verify if the SSL certificate has a valid X.509 certificate property. “knife ssl check” and “knife ssl fetch” could be used to troubleshoot communication errors with Chef Server. This process is not valid for verifying communication with Hosted Chef Servers.
execute resources in Chef is used to execute a single command. All commands executed via execute resources are not idempotent and are specific to the environment in which it’s run. We need to use guards like “not_if”, “only_if” to make the execution of the resource idempotent. During a Chef Client run, guards property verifies the state of the Chef node. "execute" resources could be run alone or in combination with other in-built Chef resources like templates, etc. "execute" resources could be used when we need to reuse existing shell scripts for infrastructure configurations. We need to specify the command to run the shell script in "execute" resource block.
For eg:
```execute 'apache_test' do command '/usr/apachectl configtest' end```
“apache_test” is the name provided for the "execute" resource block. The actual command run is “/usr/apachectl configtest”.
Execute resource could have only two actions, nothing and run. If the action specified is "run", the command provided is executed. If the action specified is nothing, the command provided in the "execute" block is prohibited from running. script resource is often confused with execute resource. Script resource is used to execute a script using an interpreter provided like bash etc
Chef nodes in your infrastructure may perform different roles at different times. For eg: Few of the Chef nodes would be web servers and one would be a load balancer. Grouping of the nodes into web servers and load balancer could be achieved in Chef using “roles” feature. The roles are defined through the role attributes. You can assign roles to your identical servers and all of them can go ahead and run the same run list mapped to the corresponding role. This helps in avoiding the process of running run lists manually on each node each time when you have many nodes performing the same function.
For configuring a new role for our node, we can make use of Knife commands. As a prerequisite, any previous roles or recipes on the run list can be removed using the “knife node run-list remove” command and then we can go ahead and add our newly added role using the “knife node run-list add role” command. The role attributes could only be defined as either ‘default’ or ‘override’ attributes. When a Chef Client run happens, the role attributes are matched against the attributes present on the node and if it takes precedence over default attributes, new settings are applied.
Bootstrap is the process by which the Chef Client is installed on the Chef nodes. Chef nodes could be physical, virtual or cloud machine. The bootstrap process can be done in two ways:
The “knife bootstrap” command is issued from the Chef workstation. The command first creates an SSH connection with the node then installs the Chef Client along with all its dependencies on the node. This command also generates keys and register the node with Chef Server. In earlier versions of Chef Client, "ORGANIZATION-validator.pem" file was used to authenticate the Chef node with the Chef Server during the first Chef Client run. Starting from Chef Client 12.1, "USER.pem" file could be used to authenticate the new Chef node. This process is also known as “validatorless bootstrap”.
We need to login to the Chef node and manually install the chef-client. Once it’s installed we need to manually set up the connection with the Chef Server.
Unattended Installs are often done on Chef nodes created in AWS Auto Scaling, AWS CloudFormation, Rackspace Auto Scale, and PXE. Chef Client is installed without SSH connection on the Chef nodes.
Security is an important feature in infrastructure management, in Chef this could be achieved through data bags. While preparing recipes for setting the different nodes we might need to provide some sensitive data as well for example like authorization credentials. It is not a good practice to hard code them as this may lead to many security risks. It is here where we can make use of data bags. Data bags are places where we can save these important data, the data gets stored in JSON format (Key-value pairs).
Data bags are indexed hence can be called whenever required by the recipes or cookbooks through a search. The data bags are encrypted and hence the contents of the data bags can be accessed only by having a decrypting key, this is how data bags give security to the chef infrastructure. Other than encryption strategies, a Chef Data Bag can be secured using a ‘Chef Vault’. Data bags can be created through the commands in the knife utility tool or manually. Data bags could be considered as a method to store global data shared across nodes.
Setting up environments is an important part of infrastructure management. We know that for the successful development of any product we need different environments like a development environment, testing environment, production environment, etc. The concept of environments in Chef is the extrapolation of the same. We at times want our Chef nodes to converge to a testing environment or a production environment configurations. Hence we can have a particular configuration for a testing environment and different configuration for the production environment. This switching of node behaviour is achieved through Chef environment settings. Environments help administrators to easily identify the stage where the particular node is a part of.
If we don’t declare any environments the Chef assumes the nodes to be in “_default” environment. Minimum one environment exists in an organisation. Environment attributes have higher precedence than default attributes of a node. Environment data could be stored in Ruby format or JSON format. An environment could be created as follows:
Chef Software hosts a repository for general-purpose community cookbooks called Chef Supermarket. Hence Chef users can use these designed and tested cookbooks wherever possible which in turn will reduce the infrastructure development time. But often we come across situations where we need to tweak the community cookbooks for our requirement i.e where wrapper cookbooks are created. Wrapper cookbooks are similar to normal cookbooks but they use recipes from other cookbooks also.One another scenario where wrapper cookbooks are created is where you have a large number of baseline cookbooks and we need to organise them for maintainability.
We create wrapper cookbooks and put in external recipes from other cookbooks for our use. This could be achieved by modifying
Wrapper classes can be further customized to your needs through some simple attribute changes. Attribute definitions and run lists of the nodes could also be version controlled using wrapper cookbooks.
chef-repo in your Chef Workstation is a directory that holds all details about cookbooks, environments, roles, and data bags.chef-repo is like source code and need to be synchronized with version control system like Git.chef-repo has following directories and files
Chef-apply is an in-built utility in Chef development kit. It helps to run a recipe from the command line. The basic syntax for chef-apply is as follows:
During Chef Server creation, you are asked to download Starter kit to Chef Workstation. After downloading, unzip the starter kit and move it to your desired path. Every Time the Starter Kit is downloaded, a new key pair is created and resets the older one. Starter Kit has all the configuration details for communicating with Chef Server. It helps us to create a folder structure for developing cookbooks. Main directories present in Starter Kit would be as follows:
Whenever a cookbook is modified, the new version details of the cookbook is updated in “metadata.rb” file and then uploaded to Chef Server using knife upload or berkshelf upload. There are 3 ways in which the new cookbook would be applied to the desired Chef nodes.
Handlers are used to solve different situations that arise during a Chef Client run. There are 3 types of handlers in Chef.
Exception and report handlers provide a wide range of information about the Chef Client run and these data could be used for analysis across the organizations.
Ohai in Chef is used to detect Chef node attributes and these are provided to chef-client during the Chef Client run. Ohai collects details about various platforms, network data, memory data, CPU data, kernel data and other configuration details. All these attributes collected are automatic attributes that are not changed even after Chef Client run. Automatic attributes are having higher precedence overall default, override, force-default and normal attributes. Ohai gets installed with the Chef Client installation.
The ohai resource is available in Chef to reload the configuration of a node. These are often used to refer back system attributes that are changed by a recipe like a recipe that creates a new user during a Chef Client run. The syntax is as follows :
ohai 'name' do plugin String action Symbol # defaults to reload if not specified end
where:
Foodcritic is an open-source tool used to detect common problems in our cookbooks like style, syntaxes, best practices, correctness etc. Foodcritic validates the Ruby code written in cookbook against several rules and creates a list of violations without running a Chef Client run. List of rules is available in Foodcritic website.
A foodcritic is often run from chef-repo with the name of the cookbook whose correctness we are going to verify. The correctness of the intention of the recipes in the cookbook is not checked instead the structure and syntax of the cookbook are checked. Whenever a Foodcritic detects violation it doesn't typically mean a change of code. For eg: Assume that rule number “FC003” defines a scenario where recipe uses a search method to get relevant data from the Chef Server. The rule suggests that an error may occur in the cookbook when the Chef Server is unavailable. We only bother to adopt this rule only if chef-solo is a part of our project workflow as chef-solo doesn’t work with Chef Server.
Food critic could also be used with Continuous Integration servers like Jenkins and Travis thus enabling automated checking within the delivery pipeline of our project.
ChefSpec is an in-built testing framework for testing resources and recipes. It’s a part of Chef Development Kit. Usually, unit tests are written in ChefSpec and is an extension of Behavior Driven Development framework called RSpec for Ruby.
A sample unit test to check if “Nginx” package is installed or not is written as follows:
describe 'nginx::default' do context 'When all attributes are default, on Ubuntu 16.04' do let(:chef_run) do runner = ChefSpec::ServerRunner.new(platform: 'ubuntu', version: '16.04') runner.converge(described_recipe) end it 'install a package' do expect(chef_run).to install_package('nginx') end end
where
Custom resources in Chef are add on resources transported as a pat of cookbooks and used by Chef Client. These are reusable in the same way as pre-defined resources in Chef. Custom resources are kept as a separate Ruby file in the resources folder of a cookbook. For eg: Assume that we need to create a custom resource called “website” that make use of in-built resources of Chef like file, package and service resources.
“website.rb “ file looks as follows:
property :home, String, default: '<h1>Welcome!</h1>' action: create do package 'nginx' service 'nginx' do action [:enable, :start] end file '/var/www/html/index.html' do content new_res.homepage end end action :delete do package 'nginx' do action :delete end end
Where
The website resource is named after the cookbook name and the file name in the resources folder. Hence if the name of our cookbook is “sample” our custom resource is defined as “sample_website” and could be used in the cookbook as follows:
sample_website 'nginx' do home '<h1>Welcome to the Sample website!</h1>' end
“Knife supermarket download” command is used to download the cookbook available in Chef Supermarket be it private or public supermarket.
The cookbooks downloaded are in the form of tar.gz files and are downloaded to the current working directory. If the specified cookbook is deprecated in the Chef Supermarket the user is notified the same and provides the details of the most recent version of the non-deprecated cookbook. For eg :
knife supermarket download httpd
downloads “httpd “cookbook from Chef Supermarket.
“knife supermarket install “ command is used to communicate with cookbooks in public or private Chef Supermarket. The downloaded cookbooks are installed in the local git repository unlike in the case of “knife supermarket download” command.“knife supermarket install “ command does the following steps
Hence this command allows updated upstream versions to be used without losing the local modifications done to the cookbook.
Chef Node is any physical, virtual or cloud machine configured by Chef Client and managed by Chef Server. A “chef-client run” is used to describe a series of steps the chef-client performs when it is configuring a node. During a chef-client run, the specified node is registered with Chef Server. This is done to avoid unwanted requests to be sent to Chef Server from chef-clients. Every request initiated by chef-client is authenticated using Chef Server API and a private key stored in “/etc/chef/client.pem” file in Chef Node.
During the first chef-client run on any node, the node won’t have the private key hence private key specified in the chef-validator placed in “/etc/chef/validation.pem” file is used. If chef-validator is unable to send an authenticated request to Chef Server the chef-client run will fail. After the node gets registered with the Chef Server chef-client attains a “client.pem” private key which will be used for all future authentication requests to the Chef server.chef-validator is not used after the initial chef-client run and hence could be deleted.
Best practices in developing a cookbook are to use
These techniques help us to reduce the debugging effort greatly.
Main debugging techniques used to detect defects in recipes and chef-client runs are
Run Chef Client with an empty run list. This helps us to make sure that the chef-client run failure is not due to the recipes added in the run list. We are also now sure that the failure is due to the configuration settings of Chef Client. chef-client run failure could also occur due to permission issues of the user at Chef Server and also on the node where Chef Client is run.
A built-in verbose logging of knife with “-v” option could be used to log messages
Chef Client could be run with verbose logging by using the “-l” option. “-L” option could also be used to specify the location of the log file.
log resource could be used to log the debug messages while running the Chef Client. This resource is also built into resource collection and run during the convergence phase. If we want to add log entries that are not added to the resource collection, use Chef:: Log. A sample log resource looks as below:
log 'mtr' do message 'A info message added.' level :info end
Where
Test-Driven Development is a DevOps practise where code is developed just to make a failing test pass. It follows a red, green, refactors cycle. In the case of Infrastructure point of view, we first write a test and see it fail. Then write the code to make the test pass and then refactor if required. TDD helps to create high quality, simpler code with high modularity.
In Chef, Test Kitchen helps us to perform TDD. We first write the InSpec test and run “kitchen verify” command to perform the test. If the test fails, enough code is written to make the test pass. We converge the node to the desired state using “kitchen converge” command. Then again “kitchen verify” command is run to verify if the test has passed. Then the code is refactored if required when all tests have passed. In places where CI/CD is used, we can use “kitchen test “ command to invoke creation of kitchen instance, converging and verifying and at last destroyed the kitchen instance. Hence helping us to detect the defects very easily and in the early stages of project development.
A cookbook is versioned whenever there is a third party component change, a bug fix, the addition of new features or improvements to existing cookbook. This helps us to easily organise the cookbook and let us know which version of the cookbook has what functionalities. This also helps us to specifically update a version of the cookbook to Chef Server and use it for chef-client runs.
A cookbook version is in the format “a.b.c” where a, b, c are decimal numbers. “a”, “b”, “c” represents major, minor and patch versions respectively. For eg: 1.1.2 version represents major and minor release version “1” with patch version “2”.Versions like “1.2a.3” or “1.2.3.4” or “3” are not allowed.
A version restriction could be attained by combining a cookbook version with an operator. Following operators are used
Cookbook versions are specified in the “metadata.rb” file located at the top of our cookbook.
include_recipe method is used to include one or more recipes from cookbooks. It might be recipes from the same cookbook or dependent cookbooks. The syntax for the include_recipe method is as follows:
include_recipe <Recipe name with the cookbook>
For eg :
include_recipe 'apache2::mod_ssl'
includes all resources from the “mod_ssl.rb” file in “apache2” cookbook to our current recipe where the “include_recipe” directive is specified. If same recipes are included multiple times using “include_recipe” directive method, only the first is included and rest is neglected.”include_recipe” directive is considered better practice than specifying the recipe in the run list especially when one cookbook depends on another cookbook. This also lessens the burdens of running the dependent cookbooks first by specifying it first in the run list of every Chef node.
In the case of wrapper cookbooks “include_recipe” directive is used to include functionalities from the dependent cookbooks. If it’s not specified but the dependent cookbooks are specified in the depends section of “metadata.rb” file, an error occurs.
Libraries store arbitrary Ruby code that could be reused across the recipes within any cookbook that depends on the library. This is often located in the library folder of our cookbooks. First and the foremost usage of libraries are to provide helper methods that reduce the code duplication and also provide a mechanism to hide the implementation logic in the recipes. Libraries get loaded first when the Chef loads our cookbooks.It make use of “ load_libraries_from_cookbook” method from the “Chef::RunContext::CookbookCompiler” class. Typical use cases of libraries are
Policyfiles are used to combine the advantages of roles and environment with Berkshelf.In usual Chef Workflow, the versions and the locations of cookbooks being used by a Chef Client are updated in “metadata.rb” file and “Berksfile”. Often this is a tedious task and a small error in these files make Chef Client apply the wrong cookbook and converged node would not acquire the required state. These problems could be solved by using a single document called Policyfiles to get the specific cookbook revisions and recipes that Chef Infra Client would apply. Policyfiles are applied on a group of nodes, cookbooks or settings. The syntax for a Policyfile.rb file is as follows:
name "name" run_list "ITEM", "ITEM", ... default_source :SOURCE_TYPE, *args cookbook "NAME" [, "VERSION_CONSTRAINT"] [, SOURCE_OPTIONS]
where
Chef shell is an interactive tool to work with resources. It helps to do REPL with the resources.chef-shell provides an easy method to test resources interactively rather than uploading our cookbook to Chef Server and applying it on Chef nodes. Breakpoints could be added on to the recipe execution using chef-shell.chef-shell could be used in three modes
Berkshelf is the dependency manager that comes with the Chef Development Kit. Whenever you create a cookbook say for eg with “chef generate cookbook” command a file called Berksfile is created on top of the cookbook directory. This file contains the source path for all cookbooks. Assume that you created a new cookbook called “my-app” which depends on another community cookbook “nginx” from public Chef Supermarket. The typical steps we follow are:
“chef_gem” and “gem_package” resources are used to install Ruby gems. Every system where Chef Client is installed has two versions of Ruby running. One is a system-wide instance of Ruby and the other is the one available only with Chef Client. “chef_gem” resource is used to install Ruby into Chef Client instance of Ruby and “gem_package” resource to install Ruby into a system-wide instance.
gem_package resource has a property called “gem_binary” property that is used by Chef Client to detect the environment settings and then install the gems. "chef_gem" resource is having all properties and options as that of “gem_package” resource except the “gem_binary” property.”chef_gem” resource always uses “CurrentGemEnvironment” where the Chef Client is running.
“chef_gem” resource has additional functions of
The attributes that should not be saved by the node is called Blacklisted attributes. These are defined in the client.rb file. Attributes are blacklisted based on attribute types. “automatic_attribute_blacklist “ defines a hash that blacklists automatic attributes. Similarly “default_attribute_blacklist”, “normal_attribute_blacklist” and “override_attribute_blacklist” are hashes that blacklist default attributes, normal attributes and override attributes respectively. The best practice is to use “automatic_attribute_blacklist “ as automatic attributes generate most data after an Ohai run. For eg:
automatic_attribute_blacklist ['filesystem']
could be used to blacklist only ‘filesystem’ attributes in the below sample attribute data
{ "filesystem" => { "/dev/disk0s2" => { "size" => "10mb" } } }
All other automatic attributes are saved by the node.
The attributes that are needed to be saved by a node are called Whitelist attributes.
These are also defined in the client.rb file. Similar to blacklist attributes, attributes are also whitelisted using attribute type.”automatic_attribute_whitelist”, “default_attribute_whitelist”, “normal_attribute_whitelist”, “ override_attribute_whitelist” are hashes used to whitelist automatic, default, normal and override attributes respectively. For eg:
automatic_attribute_whitelist ['network/interfaces/']
could be used to whitelist only network attributes among the automatic attributes generated like below:
{ "network" => { "interfaces" => { "eth0" => {...}, "eth1" => {...}, } } }
chef-solo is a command where Chef Client is run in a way that it doesn’t require Chef Server to get the required cookbooks.chef-solo make use of the local mode of the chef-client run. It doesn’t require authorisation as in the case of Chef Servers. It also doesn’t provide a centralised distribution of cookbooks or centralised API to interact with infrastructure components. Cookbooks could be loaded from two different locations i.e from a local directory or a URL where the tar.gz archive is present. In chef-solo, the node objects are stored in the form of JSON files in a local disk rather than as node objects in Chef Server. For eg:
chef-solo -c ~/solo.rb -j ~/node.json -r http://www.sample.com/chef-solo.tar.gz
runs chef-solo with solo.rb configuration file using node.json file and retrieves cookbook from the http://www.sample.com/chef-solo.tar.gz URL.
The basic workflow for chef-solo is as follows:
Ohai framework provides a mechanism to create our own customised plugins to get more details about a Chef Node. For eg: if we want to find out if a Chef node is a virtual machine or not, no Ohai plugin gathers this information so we need to create a plugin for the same. Ohai makes uses of Ruby-based DSL to create plugins. Ohai plugins are usually kept in “lib/ohai/plugins” directory in the repository. A sample Ohai plugin will look like below:
Ohai.plugin(:Sample) do provides "level" collect_data do level 100 end end
where
Ohai plugins are tested in IRB Ruby shell. This helps us to run plugins without performing actual Chef Client runs or configuring nodes. After testing is complete and we need to run the plugins we have to specify the path of the new plugin by specifying Ohai::Config[:plugin_path] << /location/of/plugins line in client.rb or solo.rb file. This helps Ohai to load the plugins correctly
kitchen.yml file is the configuration file for the Test Kitchen. All details needed to create a sandbox environment for testing our infrastructure using Chef is included in .kitchen.yml file
Syntax of a .kitchen.yml file is as follows:
The basic structure of a .kitchen.yml file is as follows:
driver: name: driver_name provisioner: name: provisioner_name verifier: name: verifier_name transport: name: transport_name platforms: - name: platform-version driver: name: driver_name suites: - name: suite_name run_list: - recipe[cookbook_name::recipe_name]
where
Cookstyle is an in-built linting tool that checks for
Cookstyle is based on RuboCop Ruby linting tool.
Cookstyle is run from the command line against a cookbook and verifies all the Ruby files in the cookbook. Cookstyle is run as cookstyle <cookbook path> and the output is provided via standard output on the terminal.
The output gives us information about the number of files present and verified, defects detected and place of defects. The result of the verification of the files is shown below:
Autocorrection facility is available for files with cookstyle warnings but care must be taken not to alter the functionality of the code after using auto-correction. Default settings in the cookstyle could be overridden by .rubocop.yml file in a cookbook.
Frozen cookbooks are those cookbooks which cannot be re-imported or modified. Hence the frozen cookbooks would not even be accidentally modified. For eg: This method helps us to protect our production environments from being modified while testing changes made to the development infrastructure. We can freeze a cookbook as follows:
Chef, a company and the creator of a configuration management tool, is an automation tool that presents a way to explain infrastructure as code. Infrastructure as code (IAC) indicates managing infrastructure by writing code (Automating infrastructure) rather than using manual processes. It can also be termed as programmable infrastructure. Chef uses a pure-Ruby, domain-specific language (DSL) for writing system configurations. is written in Ruby and Erlang. It utilises a pure-Ruby, domain-specific language (DSL) for writing system configuration "recipes". Chef is proficient in streamlining the task of configuring and maintaining a company's servers and integrating with cloud-based platforms such as Internap, Amazon EC2, Google Cloud Platform, Oracle Cloud, OpenStack, SoftLayer, Microsoft Azure, and Rackspace to automatically provision and configure new machines. Chef’s versatile and affordable features make it a favourite in providing solutions for both small and large scale systems. You can learn more about all these integrations with Chef DevOps training.
Chef’s business is expanding exponentially with annual recurring revenue increase expediting as the company scales. More than half of the Fortune 50 has Chef as one of their prime applications and 80 per cent of Chef’s revenue comes from enterprise businesses.
Top companies like HP, Amazon Web Services, Hewlett-Packard, Facebook, IBM, Microsoft, Oracle and Cisco use Chef as one of the software in their workflow and are in pursuit of Chef Developer and Full Stack engineers.
None of us can consider Interviews as a piece of cake. However, it becomes easy to handle your interviews if you are prepared with these Chef interview questions for experienced and freshers to help you in pursuing your dream career. Responding quickly and effectively to questions asked by the employers is a must in an interview. As these interview questions on Chef are very obvious, your prospective recruiters will anticipate you to be able to answer the same. These Chef interview questions and answers will boost your spirit required to ace the interview. You can also explore DevOps online courses for a comprehensive interview experience.
These Chef programming interview questions will help you to get your dream job either in Data Science, Machine Learning or just Chef coding. These Chef interview questions and answers for experienced professionals will undoubtedly raise your confidence to handle any relevant interview and will prepare you to answer the most difficult questions in the most ideal way. Suggested by experts, these Chef developer interview questions have proven to be of great value.
Both the job aspirants and even the recruiters may refer to these Chef basic interview questions in order to know the appropriate questions they need to assess a candidate.
Make a mark in your career with the next Chef interview. Create your own destiny and all the best.
Submitted questions and answers are subjecct to review and editing,and may or may not be selected for posting, at the sole discretion of Knowledgehut.
Get a 1:1 Mentorship call with our Career Advisor
By tapping submit, you agree to KnowledgeHut Privacy Policy and Terms & Conditions