{"id":63,"date":"2026-10-14T14:32:13","date_gmt":"2026-10-14T14:32:13","guid":{"rendered":"http:\/\/www.scmgalaxy.com\/tutorials\/2015\/11\/27\/puppet-training\/"},"modified":"2026-10-14T14:32:13","modified_gmt":"2026-10-14T14:32:13","slug":"puppet-training","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/puppet-training\/","title":{"rendered":"Puppet Training Agenda: A Practical Roadmap from Basics to Real-World Automation"},"content":{"rendered":"<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2015\/11\/puppet-training.png\" alt=\"Puppet training agenda\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\"><em>Originally published on 2015-11-27; fully revised and updated.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This guide turns the original <strong>Puppet training outline<\/strong> into a practical roadmap for DevOps engineers, system administrators, and platform teams. You will learn what each topic area covers, how a Puppet run works end to end, and which manifests, commands, and tooling concepts are most useful to practice first.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Course agenda and learning outcomes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The source post is primarily an agenda. Grouped into learning blocks, it covers fundamentals through operational tooling:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Configuration management basics:<\/strong> why configuration management matters and how to access working files.<\/li><li><strong>Puppet infrastructure:<\/strong> agents, Puppet master\/server concepts, orchestration context, and cross-platform operation.<\/li><li><strong>Run cycle internals:<\/strong> fact gathering, node matching, and catalog compilation.<\/li><li><strong>Puppet language primer:<\/strong> resources, types, simple manifests, and conditional logic using facts.<\/li><li><strong>Environment organization:<\/strong> node definitions, reusable modules, Forge usage, class parameters, and Hiera-driven data.<\/li><li><strong>Operational extensions:<\/strong> MCollective topics, reporting, and ecosystem tooling such as Librarian-Puppet and r10k.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Puppet architecture and run cycle<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A core learning objective is understanding the <strong>agent-to-server run cycle<\/strong> and where data, code, and reports move during enforcement.<\/p>\n\n\n\n<pre class=\"mermaid\">\nflowchart TD\n    A[Agent starts run] --> B[Collect facts]\n    B --> C[Send facts to Puppet server]\n    C --> D[Match node data]\n    D --> E[Compile catalog]\n    E --> F[Return catalog to agent]\n    F --> G[Enforce resources]\n    G --> H[Send run report]\n    H --> I[Review and orchestrate changes]\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Core components to understand<\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Agent:<\/strong> gathers system facts and applies the desired state.<\/li><li><strong>Puppet server (historically master):<\/strong> compiles catalogs from manifests, modules, and data.<\/li><li><strong>Modules:<\/strong> reusable units of Puppet code.<\/li><li><strong>Hiera:<\/strong> externalized data for class parameters and environment-specific values.<\/li><li><strong>Reporting and orchestration layer:<\/strong> visibility and controlled execution at scale.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Hands-on manifests and commands to practice<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The agenda explicitly includes applying manifests, working with Puppet types, and using fact-based conditionals. The examples below align with those objectives.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Command<\/th><th>Best for<\/th><th>Execution model<\/th><\/tr><\/thead><tbody><tr><td>puppet apply<\/td><td>Local testing of a manifest<\/td><td>Runs directly on the node without an agent-server exchange<\/td><\/tr><tr><td>puppet agent -t<\/td><td>End-to-end policy enforcement<\/td><td>Agent contacts Puppet server, fetches catalog, and applies it<\/td><\/tr><\/tbody><\/table><\/figure>\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-puppet\">package { <span class=\"hljs-string\">'nginx'<\/span>:\n  ensure =&gt; installed,\n}\n\nfile { <span class=\"hljs-string\">'\/etc\/nginx\/conf.d\/training.conf'<\/span>:\n  ensure  =&gt; file,\n  content =&gt; <span class=\"hljs-string\">\"server { listen 80; root \/var\/www\/html; }\\\\n\"<\/span>,\n  <span class=\"hljs-keyword\">require<\/span> =&gt; Package&#91;<span class=\"hljs-string\">'nginx'<\/span>],\n}\n\nservice { <span class=\"hljs-string\">'nginx'<\/span>:\n  ensure    =&gt; running,\n  enable    =&gt; <span class=\"hljs-keyword\">true<\/span>,\n  subscribe =&gt; File&#91;<span class=\"hljs-string\">'\/etc\/nginx\/conf.d\/training.conf'<\/span>],\n}<\/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<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-puppet\"><span class=\"hljs-keyword\">if<\/span> $facts&#91;<span class=\"hljs-string\">'os'<\/span>]&#91;<span class=\"hljs-string\">'family'<\/span>] == <span class=\"hljs-string\">'RedHat'<\/span> {\n  $web_pkg = <span class=\"hljs-string\">'httpd'<\/span>\n} elsif $facts&#91;<span class=\"hljs-string\">'os'<\/span>]&#91;<span class=\"hljs-string\">'family'<\/span>] == <span class=\"hljs-string\">'Debian'<\/span> {\n  $web_pkg = <span class=\"hljs-string\">'apache2'<\/span>\n} <span class=\"hljs-keyword\">else<\/span> {\n  fail(<span class=\"hljs-string\">'Unsupported OS family for this lab'<\/span>)\n}\n\npackage { $web_pkg:\n  ensure =&gt; installed,\n}<\/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=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css language-bash\"><span class=\"hljs-selector-tag\">sudo<\/span> <span class=\"hljs-selector-tag\">puppet<\/span> <span class=\"hljs-selector-tag\">apply<\/span> <span class=\"hljs-selector-tag\">site<\/span><span class=\"hljs-selector-class\">.pp<\/span> <span class=\"hljs-selector-tag\">--noop<\/span>\n<span class=\"hljs-selector-tag\">sudo<\/span> <span class=\"hljs-selector-tag\">puppet<\/span> <span class=\"hljs-selector-tag\">apply<\/span> <span class=\"hljs-selector-tag\">site<\/span><span class=\"hljs-selector-class\">.pp<\/span>\n<span class=\"hljs-selector-tag\">sudo<\/span> <span class=\"hljs-selector-tag\">puppet<\/span> <span class=\"hljs-selector-tag\">agent<\/span> <span class=\"hljs-selector-tag\">-t<\/span>\n<span class=\"hljs-selector-tag\">sudo<\/span> <span class=\"hljs-selector-tag\">puppet<\/span> <span class=\"hljs-selector-tag\">facts<\/span> <span class=\"hljs-selector-tag\">show<\/span> <span class=\"hljs-selector-tag\">os<\/span>\n<span class=\"hljs-selector-tag\">sudo<\/span> <span class=\"hljs-selector-tag\">puppet<\/span> <span class=\"hljs-selector-tag\">resource<\/span> <span class=\"hljs-selector-tag\">service<\/span> <span class=\"hljs-selector-tag\">nginx<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><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-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php language-yaml\">---\nprofile::web::package_name: <span class=\"hljs-string\">\"nginx\"<\/span>\nprofile::web::service_name: <span class=\"hljs-string\">\"nginx\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><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\">Advanced tooling topics from the agenda<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The original outline also references dependency management, environment deployment, and external classification\/reporting concepts.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Tool<\/th><th>Best for<\/th><th>Notes for modern teams<\/th><\/tr><\/thead><tbody><tr><td>Librarian-Puppet<\/td><td>Managing Puppet module dependencies<\/td><td>Common in older workflows; still seen in legacy estates.<\/td><\/tr><tr><td>r10k<\/td><td>Deploying environments and modules from a control repository<\/td><td>Useful for branch-based environment promotion.<\/td><\/tr><tr><td>Puppet Dashboard \/ ENC concepts<\/td><td>External node classification and reporting<\/td><td>Concept remains important even when tooling choices differ.<\/td><\/tr><tr><td>MCollective<\/td><td>Live fleet interaction and orchestration-style operations<\/td><td>Frequently encountered in legacy training material and older deployments.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Registration links and preserved source resources<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Original registration links from the source page: <a href=\"events\/register\/index.html\">legacy registration page<\/a> and <a href=\"https:\/\/docs.google.com\/a\/scmgalaxy.com\/forms\/d\/1kZs21fbihV4AK2a530-9rHbCuCJR-lQj1aAmC3C0aKE\/viewform\" target=\"_blank\" rel=\"noopener\">Google Form registration<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/docs.google.com\/a\/scmgalaxy.com\/forms\/d\/1kZs21fbihV4AK2a530-9rHbCuCJR-lQj1aAmC3C0aKE\/viewform\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.scmgalaxy.com\/tutorials\/wp-content\/uploads\/2014\/07\/registernow.jpg\" alt=\"Register now\" width=\"232\" height=\"104\" \/><\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The original page also contained a YouTube gallery element that currently reports an API key restriction error; the referenced setup tutorial is preserved here: <a href=\"https:\/\/www.youtube.com\/watch?v=ZCfrNvu6nMc\" target=\"_blank\" rel=\"noopener\">YouTube API key setup video<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Common pitfalls<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Learning syntax without understanding the <strong>run cycle<\/strong> (facts, compilation, and enforcement).<\/li><li>Hardcoding environment values in manifests instead of separating data in <strong>Hiera<\/strong>.<\/li><li>Skipping safe validation runs such as <strong>&#8211;noop<\/strong> before applying changes.<\/li><li>Using community modules without checking dependencies, parameters, and platform fit.<\/li><li>Treating legacy tools as mandatory instead of validating current standards in your Puppet platform.<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This revised guide converts the original Puppet course outline into a clear learning path for DevOps and platform teams. It covers architecture, run cycle, hands-on manifests, ecosystem tools, and common implementation pitfalls.<\/p>\n","protected":false},"author":1,"featured_media":3180,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[8],"tags":[1253,884,94,159,1255,1259,1254,1260,1256,1257,1258,130,96],"class_list":["post-63","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-training","tag-agenda","tag-classroom","tag-online","tag-puppet","tag-puppet-course","tag-puppet-course-content","tag-puppet-training","tag-puppet-training-agenda","tag-puppet-training-course","tag-puppet-training-program","tag-puppet-training-session","tag-scmgalaxy","tag-training"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/63","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=63"}],"version-history":[{"count":4,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/63\/revisions"}],"predecessor-version":[{"id":79343,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/63\/revisions\/79343"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media\/3180"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=63"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=63"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=63"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}