I had an opportunity to use Chef and wanted to know it systematically, so I read Chef Practical Guide. I’ll leave notes for myself.
Overview
- There are two types of operation modes depending on whether a management server is involved. The first is a server-client model using Chef Server as a management server. In addition to the local terminal and managed nodes, a Chef Server is required. Communication occurs between the local terminal and Chef Server, and between Chef Server and nodes (Chef Client). Strong against increasing number of nodes. The second is a standalone model using Chef Solo. Neither Chef Server nor Chef Client is required. Often used in small-scale environments. Both are implemented in Ruby, so they can be installed by
gemlikegem install chef knife-solo berkshelf. - It has a hierarchical structure of repository (kitchen), cookbook, and recipe. The repository is version-controlled by Git, etc. Place self-created cookbooks in
site-cookbooks, external cookbooks incookbooks, globally scoped data for the entire repository indata_bags, environment information like dev/prod inenvironments, and node-specific configuration information (node objects) innodes. Also, describe the list of dependent external cookbooks inBerksfile.
Cookbook Implementation
- When managing multiple nodes with the same configuration, define a role that groups the nodes. Create
<repository>/roles/<role name>.jsonand writerun_list, etc. You can also override Attributes.default_attributesdefines things that are not defined, andoverride_attributesforcibly overwrites. - There is a mechanism called Attribute that manages key-values. You can set them yourself or automatically extract them from the system. When automatically extracting, the result of the
ohaicommand is used. Conventionally, use symbols likenode[:platform]for keys of values obtained byohai, and use strings likenode["httpd"]["port"]for keys defined in Node objects. Attributes can have default values defined in<cookbook name>/attributes/defaults.rb. Attribute priority order is: Node object > Role > Environment > Recipe Attribute > Cookbook Attribute. - The
cookbook_fileresource transfers files under<cookbook name>/files, and thefileresource is used to newly create files. - There are resources like
ifconfig,mount,gem_package,git,http_request,route,ruby_block. If there are things that cannot be managed even using these resources, use thescriptresource. However, you need to ensure idempotency yourself by usingnot_if,only_if, etc. well. - After placing configuration files, you can reload services like
notifies :reload, "service[httpd]". Alternatively, you can define in the opposite direction bysubscribes :reload "template[/etc/httpd.conf]". Both behave the same, queued and executed together. - If indentation becomes deep with
ifstatements and readability decreases, it’s good to use conditional actions likeonly_if. - Resources written in recipes are executed at convergence timing after compilation, but other Ruby code is executed at compile time. If you want to write Ruby code executed at convergence timing, use the
ruby_blockresource. - A series of resources and processing can be implemented as a
Definitionlike a macro.
Chef Solo
- When the cookbook development server and managed nodes are the same, create a cookbook with
knife cookbook create <cookbook name>and execute the cookbook withchef-solo -o <cookbook name>. I wonder if this usage is rare. - When the development server and managed nodes are different, use
knife-soloon the development server. Theknife-solocommand transfers the local cookbook to the node and executeschef-solo. First, on the development server, prepare the repository withknife solo init .. Next, installchef-soloon the managed node withknife solo prepare <hostname>. Then create a cookbook withknife cookbook create <cookbook name> -o <repository>/site-cookbooks. After that, edit the cookbook and write{'run_list': ["recipe[<cookbook name>:<recipe name>]"]}in<repository>/nodes/<hostname>.json. If you omit<recipe name>,default.rbis referenced. Finally, provision the node withknife solo cook <hostname>. Note that there is also aknife solo bootstrap <hostname>command that combinesknife solo prepare <hostname>andknife solo cook <hostname>. Also, useknife solofor things that depend only onchef-solo, and useknifefor others.
Other
- You can integration test cookbooks using
Test Kitchen. Launch multiple OSes withVagrant, etc. Test execution is done byserverspecafter applying the cookbook. If you want to test behavior without actually applying tests, useChefSpec. - Search for external cookbooks with
knife cookbook site search <cookbook name>and addcookbook '<cookbook>'toBerksfile. Then, with theberkscommand, they are downloaded and expanded to thecookbooksdirectory. - Opscode, Basecamp, RiotGames, aws, engineyard, pivotal-sprout, etc. publish community cookbooks.
- Chef Server authenticates by checking
validation.pemon both sides when registering a new client. Then, it issues a private key to the client. - You can check the last time Chef Client was executed with
knife status. - Chef’s idempotency and emergency rollback are incompatible. Therefore, application deployment by Chef is not ideal.
- To prevent forgetting to apply cookbooks, periodically execute Chef Solo or use Server/Client configuration for automatic application.
- Plugins for
knifeandohaicommands can be easily implemented by placing Ruby code in specified directories.