{"id":427,"date":"2026-10-14T08:11:36","date_gmt":"2026-10-14T08:11:36","guid":{"rendered":"http:\/\/www.scmgalaxy.com\/tutorials\/2015\/09\/02\/chef-configuration-management-interview-questions-and-answers-2\/"},"modified":"2026-10-14T08:11:36","modified_gmt":"2026-10-14T08:11:36","slug":"chef-configuration-management-interview-questions-and-answers-2","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/chef-configuration-management-interview-questions-and-answers-2\/","title":{"rendered":"Chef Interview Q&#038;A (Part 2): Resources, Run-Lists, Bootstrap, and Test Kitchen"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Chef interview rounds usually go beyond definitions and test whether you understand <strong>convergence behavior<\/strong>, <strong>resource order<\/strong>, and <strong>node lifecycle operations<\/strong>. This revised guide turns the original Q&amp;A into a concise field reference for interview prep and real operations work.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Originally published on 2015-09-02; fully revised and updated.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Original source attribution in the post pointed to <a href=\"http:\/\/learn.chef.io\" target=\"_blank\" rel=\"noopener noreferrer\">learn.chef.io<\/a>. Community cookbooks referenced in the material are available through <a href=\"https:\/\/supermarket.chef.io\" target=\"_blank\" rel=\"noopener noreferrer\">Chef Supermarket<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Core Chef concepts interviewers expect<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Resource:<\/strong> A unit of desired state (for example, a package, service, or file).<\/li><li><strong>Recipe:<\/strong> An ordered collection of resources that applies configuration policy.<\/li><li><strong>Cookbook:<\/strong> A package of recipes plus supporting files (templates, attributes, libraries, etc.).<\/li><li><strong>Node:<\/strong> A managed compute instance (VM, physical host, or container host context).<\/li><li><strong>Run-list:<\/strong> The ordered list of recipes\/roles a node applies during a Chef run.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Resource execution order and default actions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Chef processes resources in the order they appear in a recipe. That ordering can be the difference between a successful converge and a failed run.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Default action behavior<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If you omit an explicit <code>action<\/code>, Chef uses that resource type\u2019s default action. For example, package resources typically default to install behavior.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php language-ruby\">package <span class=\"hljs-string\">'httpd'<\/span>\n<span class=\"hljs-comment\"># No action specified; package resource uses its default action.<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Order-sensitive versus order-insensitive cases<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php language-ruby\"><span class=\"hljs-comment\"># Works in expected sequence: package first, service second<\/span>\npackage <span class=\"hljs-string\">'httpd'<\/span>\n\nservice <span class=\"hljs-string\">'httpd'<\/span> <span class=\"hljs-keyword\">do<\/span>\n  action &#91;:enable, :start]\nend<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php language-ruby\"><span class=\"hljs-comment\"># Risky sequence: service before package<\/span>\nservice <span class=\"hljs-string\">'httpd'<\/span> <span class=\"hljs-keyword\">do<\/span>\n  action &#91;:enable, :start]\nend\n\npackage <span class=\"hljs-string\">'httpd'<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Comparison<\/th><th>Equivalent?<\/th><th>Why<\/th><\/tr><\/thead><tbody><tr><td><code>package<\/code> then <code>service<\/code> vs <code>service<\/code> then <code>package<\/code><\/td><td>No<\/td><td>Chef executes top-to-bottom; service actions may fail if package\/service unit is not present yet.<\/td><\/tr><tr><td><code>action [:enable, :start]<\/code> vs <code>action [:start, :enable]<\/code><\/td><td>Not strictly<\/td><td>Both can reach similar end state, but operation order differs and can matter for notifications\/timing.<\/td><\/tr><tr><td>Same file resource attributes in different order<\/td><td>Yes<\/td><td>Attribute line order inside a single resource block is not the key behavior driver in this case.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript language-ruby\">service <span class=\"hljs-string\">'httpd'<\/span> <span class=\"hljs-keyword\">do<\/span>\n  action &#91;:stop, :disable]\nend<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Recipe, cookbook, and run-list relationships<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Interviews often probe whether you can connect authoring to execution: resources live in recipes, recipes are packaged as cookbooks, and run-lists define what each node applies and in what order.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript language-bash\">knife node run_list add web1 <span class=\"hljs-string\">'recipe&#91;apache::default]'<\/span>\nknife node show web1 -a run_list<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The original material also highlights two server consumption models: running Chef Server on your own infrastructure or using a hosted offering, and using the Starter Kit credentials to securely connect with <code>knife<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">chef-apply vs chef-client vs knife<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Tool<\/th><th>Best for<\/th><th>Typical scope<\/th><\/tr><\/thead><tbody><tr><td><code>chef-apply<\/code><\/td><td>Quick local testing\/learning of a single recipe<\/td><td>One recipe at a time<\/td><\/tr><tr><td><code>chef-client<\/code><\/td><td>Normal node convergence in managed environments<\/td><td>Applies node run-list (one or more cookbooks\/recipes)<\/td><\/tr><tr><td><code>knife<\/code><\/td><td>Workstation-to-server operations<\/td><td>Bootstrap, upload cookbooks, inspect nodes, remote execution<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php language-bash\">chef-apply .\/example.rb\nchef-client\nknife node <span class=\"hljs-keyword\">list<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Node bootstrap and first converge workflow<\/h2>\n\n\n\n<pre class=\"mermaid\">\nflowchart TD\n    A[Prepare workstation credentials] --> B[Run knife bootstrap]\n    B --> C[Node installs chef-client]\n    C --> D[Node registers with Chef Server]\n    D --> E[Node pulls assigned run-list]\n    E --> F[Chef Infra Client converges resources]\n    F --> G{Configuration drift remains}\n    G -- yes --> H[Update cookbook and upload]\n    H --> F\n    G -- no --> I[Node stays in desired state]\n<\/pre>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php language-bash\">knife bootstrap NODE_IP \\\n  -x USER \\\n  -P <span class=\"hljs-string\">'PASSWORD'<\/span> \\\n  --sudo \\\n  --node-name web1 \\\n  --run-<span class=\"hljs-keyword\">list<\/span> <span class=\"hljs-string\">'recipe&#91;apache::default]'<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Uploading and applying cookbook updates<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">After editing a cookbook, upload it to Chef Server and trigger a converge on target nodes.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript language-bash\">knife cookbook upload awesome_customers\nknife ssh <span class=\"hljs-string\">'name:web1'<\/span> <span class=\"hljs-string\">'sudo chef-client'<\/span>\nssh user@web1.example.com <span class=\"hljs-string\">'sudo chef-client'<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The source also references Semantic Versioning guidance: setting cookbook version <code>1.0.0<\/code> once it is considered production-ready.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Template example: render node data into an HTML page<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This ERB example from the original content demonstrates using node attributes in a template:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml language-erb\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">html<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>hello from <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">%=<\/span> <span class=\"hljs-attr\">node<\/span>&#91;'<span class=\"hljs-attr\">fqdn<\/span>'] %&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">pre<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">%=<\/span> <span class=\"hljs-attr\">node<\/span>&#91;'<span class=\"hljs-attr\">hostname<\/span>'] %&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">%=<\/span> <span class=\"hljs-attr\">node<\/span>&#91;'<span class=\"hljs-attr\">platform<\/span>'] %&gt;<\/span> - <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">%=<\/span> <span class=\"hljs-attr\">node<\/span>&#91;'<span class=\"hljs-attr\">platform_version<\/span>'] %&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">%=<\/span> <span class=\"hljs-attr\">node<\/span>&#91;'<span class=\"hljs-attr\">memory<\/span>']&#91;'<span class=\"hljs-attr\">total<\/span>'] %&gt;<\/span> RAM\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">%=<\/span> <span class=\"hljs-attr\">node<\/span>&#91;'<span class=\"hljs-attr\">cpu<\/span>']&#91;'<span class=\"hljs-attr\">total<\/span>'] %&gt;<\/span> CPUs\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">pre<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">html<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Then upload the cookbook and run <code>chef-client<\/code> on the node to apply the updated template.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Local cookbook testing with Test Kitchen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For faster development cycles, Test Kitchen can create ephemeral instances, converge cookbooks, and tear instances down after validation.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Component<\/th><th>Role<\/th><th>How it fits the workflow<\/th><\/tr><\/thead><tbody><tr><td>Test Kitchen<\/td><td>Test orchestrator<\/td><td>Defines platform\/suite matrix and runs converge\/verify lifecycle.<\/td><\/tr><tr><td>Vagrant<\/td><td>Environment manager<\/td><td>Bridges Kitchen and local providers; handles VM definitions and lifecycle commands.<\/td><\/tr><tr><td>VirtualBox<\/td><td>Virtualization provider<\/td><td>Runs the actual local virtual machines used by Kitchen in this setup.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css language-yaml\"><span class=\"hljs-selector-tag\">---<\/span>\n<span class=\"hljs-selector-tag\">driver<\/span>:\n  <span class=\"hljs-selector-tag\">name<\/span>: <span class=\"hljs-selector-tag\">vagrant<\/span>\n\n<span class=\"hljs-selector-tag\">provisioner<\/span>:\n  <span class=\"hljs-selector-tag\">name<\/span>: <span class=\"hljs-selector-tag\">chef_zero<\/span>\n\n<span class=\"hljs-selector-tag\">platforms<\/span>:\n  <span class=\"hljs-selector-tag\">-<\/span> <span class=\"hljs-selector-tag\">name<\/span>: <span class=\"hljs-selector-tag\">centos-6<\/span><span class=\"hljs-selector-class\">.6<\/span>\n  <span class=\"hljs-selector-tag\">-<\/span> <span class=\"hljs-selector-tag\">name<\/span>: <span class=\"hljs-selector-tag\">centos-6<\/span><span class=\"hljs-selector-class\">.5<\/span>\n\n<span class=\"hljs-selector-tag\">suites<\/span>:\n  <span class=\"hljs-selector-tag\">-<\/span> <span class=\"hljs-selector-tag\">name<\/span>: <span class=\"hljs-selector-tag\">default<\/span>\n    <span class=\"hljs-selector-tag\">run_list<\/span>:\n      <span class=\"hljs-selector-tag\">-<\/span> <span class=\"hljs-selector-tag\">recipe<\/span><span class=\"hljs-selector-attr\">&#91;motd::default]<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php language-bash\">kitchen <span class=\"hljs-keyword\">list<\/span>\nkitchen converge\nkitchen login <span class=\"hljs-keyword\">default<\/span>-centos<span class=\"hljs-number\">-66<\/span>\nkitchen login <span class=\"hljs-keyword\">default<\/span>-centos<span class=\"hljs-number\">-65<\/span>\nkitchen destroy<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Best practices and common pitfalls<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Explain <strong>resource order<\/strong> clearly in interviews; it is one of the most common failure patterns.<\/li><li>Use <strong>run-lists intentionally<\/strong>; sequence across cookbooks can affect service readiness.<\/li><li>Test cookbook changes in <strong>ephemeral environments<\/strong> before production convergence.<\/li><li>Keep cookbook versions meaningful and increment with change impact.<\/li><li>Do not assume old platform examples (for example, CentOS 6.x) are suitable for current production baselines.<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>A practical rewrite of classic Chef interview questions, focused on how Chef resources converge, how run-lists drive node configuration, and how to test cookbooks safely. Includes command examples, workflow diagrams, and comparison tables.<\/p>\n","protected":false},"author":1,"featured_media":3372,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[52],"tags":[641,647,407,1523,1518,1520,1519,282,1517,766,507,1521,244,482,637,1522],"class_list":["post-427","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-interview-questions-answers","tag-answers","tag-best","tag-chef","tag-chef-configuration-management-interview","tag-chef-interview","tag-chef-interview-qa","tag-chef-interview-questions-and-answers","tag-configuration","tag-configuration-management","tag-interview","tag-list","tag-list-of-chef-interview-questions-and-answers","tag-management","tag-questions","tag-top","tag-top-chef-interview-questions-and-answers"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/427","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=427"}],"version-history":[{"count":5,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/427\/revisions"}],"predecessor-version":[{"id":79301,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/427\/revisions\/79301"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media\/3372"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=427"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=427"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=427"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}