{"id":426,"date":"2026-10-14T08:01:27","date_gmt":"2026-10-14T08:01:27","guid":{"rendered":"http:\/\/www.scmgalaxy.com\/tutorials\/2015\/09\/02\/chef-configuration-management-interview-questions-and-answers\/"},"modified":"2026-10-14T08:01:27","modified_gmt":"2026-10-14T08:01:27","slug":"chef-configuration-management-interview-questions-and-answers","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/chef-configuration-management-interview-questions-and-answers\/","title":{"rendered":"Chef Interview Questions, Explained: Resources, Run-Lists, Bootstrapping, and Test Kitchen"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Chef interviews and day-to-day operations often revolve around the same fundamentals: resources, recipes, cookbooks, run-lists, node bootstrapping, and local testing. This guide is for DevOps engineers who want clear, interview-ready answers plus production-oriented examples.<\/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\"><em>Source material: <a href=\"http:\/\/learn.chef.io\">learn.chef.io<\/a> (original Q&amp;A format), reorganized here into a structured reference.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Core Chef concepts interviewers ask most often<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Concept<\/th><th>What it means in practice<\/th><th>Interview-ready answer<\/th><\/tr><\/thead><tbody><tr><td>Resource<\/td><td>A unit of desired state (package, service, file, template, user, etc.).<\/td><td>A resource describes <em>what state must exist<\/em>, not just a command to run.<\/td><\/tr><tr><td>Recipe<\/td><td>An ordered collection of resources.<\/td><td>A recipe defines configuration policy for part of a system.<\/td><\/tr><tr><td>Cookbook<\/td><td>A package of recipes plus templates, files, attributes, and metadata.<\/td><td>A cookbook is the reusable delivery unit; a recipe is one part inside it.<\/td><\/tr><tr><td>Run-list<\/td><td>Ordered list of recipes\/roles a node applies.<\/td><td>Run-list controls <em>what<\/em> runs and <em>in which order<\/em>.<\/td><\/tr><tr><td>Node<\/td><td>Any managed machine (VM, bare metal, or instance).<\/td><td>A node is the compute target that runs chef-client and converges policy.<\/td><\/tr><tr><td>Starter Kit<\/td><td>Workstation files and credentials for secure Chef Server access.<\/td><td>It contains keys\/config needed for authenticated communication.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Why resource order and action order matter<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Chef applies resources in the order they are declared during convergence. That means ordering can decide whether a run succeeds or fails.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript language-ruby\">package <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-1\"><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 example above typically works because the package is installed before the service is managed.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" 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;:enable, :start]\nend\n\npackage <span class=\"hljs-string\">'httpd'<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><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\">This order can fail if the service provider cannot manage <code>httpd<\/code> before the package exists.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Case<\/th><th>Equivalent?<\/th><th>Why<\/th><\/tr><\/thead><tbody><tr><td>package then service<\/td><td>No (vs service then package)<\/td><td>Resource declaration order changes convergence behavior.<\/td><\/tr><tr><td>action [:enable, :start] vs [:start, :enable]<\/td><td>Not strictly identical<\/td><td>Actions are executed in listed order; boot\/runtime side effects may differ.<\/td><\/tr><tr><td>Different ordering of attributes inside one resource<\/td><td>Usually yes<\/td><td>Attribute line order inside the same resource does not typically change outcome.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript language-ruby\">file <span class=\"hljs-string\">'\/etc\/motd'<\/span> <span class=\"hljs-keyword\">do<\/span>\n  owner <span class=\"hljs-string\">'root'<\/span>\n  group <span class=\"hljs-string\">'root'<\/span>\n  mode <span class=\"hljs-string\">'0755'<\/span>\n  <span class=\"hljs-attr\">action<\/span> :create\nend\n\nfile <span class=\"hljs-string\">'\/etc\/motd'<\/span> <span class=\"hljs-keyword\">do<\/span>\n  <span class=\"hljs-attr\">action<\/span> :create\n  mode <span class=\"hljs-string\">'0755'<\/span>\n  group <span class=\"hljs-string\">'root'<\/span>\n  owner <span class=\"hljs-string\">'root'<\/span>\nend<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><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\">chef-apply vs chef-client<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Command<\/th><th>Best for<\/th><th>Typical scope<\/th><th>Common use<\/th><\/tr><\/thead><tbody><tr><td>chef-apply<\/td><td>Quick local experiments<\/td><td>Single recipe file<\/td><td>Learning, prototyping, one-off validation<\/td><\/tr><tr><td>chef-client<\/td><td>Managed node convergence<\/td><td>Run-list and cookbook content<\/td><td>Production configuration runs via Chef Server or local mode<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Chef Server options and bootstrap prerequisites<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The original material describes two common server patterns: self-hosted Chef Server and hosted Chef offerings.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Option<\/th><th>Control<\/th><th>Operational overhead<\/th><\/tr><\/thead><tbody><tr><td>Self-hosted Chef Server<\/td><td>High<\/td><td>You manage installation, upgrades, backup, and availability.<\/td><\/tr><tr><td>Hosted Chef service<\/td><td>Lower<\/td><td>Provider operates the control plane; you focus on policy and nodes.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">For bootstrapping a node from your workstation, you generally need:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Node host name or reachable IP address<\/li><li>A login user with privilege to install software<\/li><li>Password authentication or (preferably) SSH key authentication<\/li><li>Workstation credentials (Starter Kit) to talk to Chef Server<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Bootstrap workflow from workstation to managed node<\/h2>\n\n\n\n<pre class=\"mermaid\">\nflowchart TD\n    A[Workstation with knife] --> B[Bootstrap target node]\n    B --> C[Install chef-client]\n    C --> D[Register node with Chef Server]\n    D --> E[Assign run list]\n    E --> F[Converge resources in order]\n    F --> G[Node checkin completes]\n    G --> H[Verify node in knife or console]\n<\/pre>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml language-bash\">knife bootstrap <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">NODE_IP<\/span>&gt;<\/span> -x <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">SSH_USER<\/span>&gt;<\/span> -i <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">PATH_TO_PRIVATE_KEY<\/span>&gt;<\/span> --sudo --node-name <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">NODE_NAME<\/span>&gt;<\/span> --run-list 'recipe&#91;apache::default]'\n\nknife node list\nknife node show <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">NODE_NAME<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><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<h2 class=\"wp-block-heading\">Common knife commands from the original Q&amp;A<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Command<\/th><th>Purpose<\/th><\/tr><\/thead><tbody><tr><td>knife node list<\/td><td>List registered nodes<\/td><\/tr><tr><td>knife node show NODE<\/td><td>View details for a specific node<\/td><\/tr><tr><td>knife cookbook upload COOKBOOK<\/td><td>Upload cookbook content to Chef Server<\/td><\/tr><tr><td>knife ssh QUERY CMD<\/td><td>Run remote commands across matching nodes<\/td><\/tr><tr><td>knife cookbook site show NAME<\/td><td>Query cookbook metadata from the community site<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Reusable community cookbooks are published on <a href=\"https:\/\/supermarket.chef.io\">Chef Supermarket<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Template and versioning example<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The original article shows rendering node facts into an HTML template. The ERB below mirrors that pattern.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" 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  <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-5\"><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<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-ruby\"><span class=\"hljs-comment\"># metadata.rb<\/span>\nversion <span class=\"hljs-string\">'1.0.0'<\/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<p class=\"wp-block-paragraph\">Using <code>1.0.0<\/code> for a production-ready first stable release matches Semantic Versioning practice.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Testing on multiple platforms with Test Kitchen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Test Kitchen helps run the same cookbook across a platform matrix. The source example uses CentOS 6.x; treat that as historical and map to currently supported images in your environment.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" 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-7\"><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-8\" 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><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><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 for interviews and real Chef usage<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Explain Chef in terms of <em>desired state<\/em> and <em>idempotent resources<\/em>, not shell scripts.<\/li><li>Call out ordering explicitly: recipe order matters; attribute line order inside a resource usually does not.<\/li><li>Use <code>chef-apply<\/code> for quick experiments, but describe <code>chef-client<\/code> for managed production convergence.<\/li><li>Show verification habits: check run-list, inspect node data, and test across multiple platforms with Test Kitchen.<\/li><li>Version cookbooks deliberately and promote through environments instead of ad-hoc edits on servers.<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This updated guide converts classic Chef interview Q&#038;A into a practical reference for real infrastructure work. It covers core concepts, execution order, bootstrap flow, key knife commands, and Test Kitchen testing patterns.<\/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-426","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\/426","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=426"}],"version-history":[{"count":7,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/426\/revisions"}],"predecessor-version":[{"id":79300,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/426\/revisions\/79300"}],"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=426"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=426"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=426"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}