{"id":224,"date":"2026-10-12T22:50:54","date_gmt":"2026-10-12T22:50:54","guid":{"rendered":"http:\/\/www.scmgalaxy.com\/tutorials\/2010\/03\/21\/power-point-ppt-configuration-management-2\/"},"modified":"2026-10-12T22:50:54","modified_gmt":"2026-10-12T22:50:54","slug":"power-point-ppt-configuration-management-2","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/power-point-ppt-configuration-management-2\/","title":{"rendered":"Configuration Management in DevOps: Concepts, Tooling, and a Practical Workflow"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Configuration management is the DevOps practice of defining a <strong>desired system state<\/strong> (packages, services, files, users, policies) and enforcing that state consistently across servers and environments. This article is for platform, SRE, and infrastructure engineers who want a clear mental model, a tool comparison, and practical implementation patterns.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Originally published on 2010-03-21T21:03:26; fully revised and updated.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <a href=\"https:\/\/www.devopsschool.com\/blog\/power-point-ppt-configuration-management-2\/\">original post<\/a> primarily embedded a SlideShare deck. The original shortcode is preserved here:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">{slideshare}[slideshare id=1117749&amp;doc=configurationmanagement-090308134227-phpapp02]{\/slideshare}<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What configuration management does in a DevOps stack<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">At its core, configuration management reduces drift between what systems <em>should<\/em> look like and what they <em>actually<\/em> look like. Instead of manually editing servers, teams define state as code and apply it repeatedly.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Desired state:<\/strong> declare the end state (for example, nginx installed and running).<\/li><li><strong>Idempotency:<\/strong> safe repeated runs without unnecessary changes.<\/li><li><strong>Version control:<\/strong> track who changed what and when.<\/li><li><strong>Auditability:<\/strong> reviewable pull requests and change history.<\/li><li><strong>Consistency:<\/strong> same baseline across dev, staging, and production.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Typical workflow from Git change to enforced state<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Most teams run configuration management through Git-based change control and automated execution.<\/p>\n\n\n\n<pre class=\"mermaid\">\nflowchart TD\n    A[Engineer updates config in Git] --> B[Pull request review]\n    B --> C[CI lint and syntax checks]\n    C --> D{Checks pass}\n    D -- No --> E[Fix and resubmit]\n    D -- Yes --> F[Merge to main branch]\n    F --> G[Run configuration management apply]\n    G --> H[Nodes converge to desired state]\n    H --> I[Drift and compliance report]\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Tool comparison: Ansible, Puppet, Chef, Salt, and Terraform<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Different tools can solve similar problems with different operating models. A quick comparison helps with initial selection.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Tool<\/th><th>Primary model<\/th><th>Best for<\/th><th>Key consideration<\/th><\/tr><\/thead><tbody><tr><td>Ansible<\/td><td>Mostly agentless push over SSH\/WinRM<\/td><td>Fast onboarding, readable YAML automation<\/td><td>Controller access and execution orchestration must be planned<\/td><\/tr><tr><td>Puppet<\/td><td>Agent-based pull model<\/td><td>Large fleets with continuous policy enforcement<\/td><td>Operational overhead for Puppet infrastructure and agent lifecycle<\/td><\/tr><tr><td>Chef<\/td><td>Agent-based pull model<\/td><td>Complex policy-driven node configuration<\/td><td>Steeper learning curve for cookbook patterns<\/td><\/tr><tr><td>Salt<\/td><td>Agent-based (minion) with SSH-based options<\/td><td>Event-driven automation and remote execution<\/td><td>Architecture choice (master\/minion vs SSH) affects operations<\/td><\/tr><tr><td>Terraform (adjacent)<\/td><td>Declarative infrastructure provisioning<\/td><td>Cloud\/network\/resource lifecycle management<\/td><td>Not a full replacement for OS and in-host app configuration<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Example: baseline Linux web server configuration with Ansible<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The example below installs nginx, ensures it is enabled and running, and deploys a managed config file. This demonstrates the desired-state and idempotent style used in configuration management.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Inventory file<\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs language-ini\">&#91;web]\nweb01.example.internal\nweb02.example.internal\n\n&#91;web:vars]\nansible_user=automation<\/code><\/span><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Playbook<\/h3>\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-yaml\">---\n- name: Configure web servers\n  <span class=\"hljs-attr\">hosts<\/span>: web\n  <span class=\"hljs-attr\">become<\/span>: <span class=\"hljs-literal\">true<\/span>\n  <span class=\"hljs-attr\">tasks<\/span>:\n    - name: Ensure nginx is installed\n      <span class=\"hljs-attr\">package<\/span>:\n        name: nginx\n        <span class=\"hljs-attr\">state<\/span>: present\n\n    - name: Ensure nginx service is enabled and running\n      <span class=\"hljs-attr\">service<\/span>:\n        name: nginx\n        <span class=\"hljs-attr\">enabled<\/span>: <span class=\"hljs-literal\">true<\/span>\n        <span class=\"hljs-attr\">state<\/span>: started\n\n    - name: Deploy nginx config\n      <span class=\"hljs-attr\">copy<\/span>:\n        src: files\/nginx.conf\n        <span class=\"hljs-attr\">dest<\/span>: <span class=\"hljs-regexp\">\/etc\/<\/span>nginx\/nginx.conf\n        <span class=\"hljs-attr\">owner<\/span>: root\n        <span class=\"hljs-attr\">group<\/span>: root\n        <span class=\"hljs-attr\">mode<\/span>: <span class=\"hljs-string\">\"0644\"<\/span>\n      <span class=\"hljs-attr\">notify<\/span>: Restart nginx\n\n  <span class=\"hljs-attr\">handlers<\/span>:\n    - name: Restart nginx\n      <span class=\"hljs-attr\">service<\/span>:\n        name: nginx\n        <span class=\"hljs-attr\">state<\/span>: restarted<\/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<h3 class=\"wp-block-heading\">Execution commands<\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs language-bash\">ansible-playbook -i inventory\/prod.ini site.yml --check\nansible-playbook -i inventory\/prod.ini site.yml<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Repository structure and environment promotion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Keeping configuration code organized makes review and promotion safer. A simple layout:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs language-text\">cm-repo\/\n\u251c\u2500\u2500 inventory\/\n\u2502   \u251c\u2500\u2500 dev.ini\n\u2502   \u251c\u2500\u2500 stage.ini\n\u2502   \u2514\u2500\u2500 prod.ini\n\u251c\u2500\u2500 group_vars\/\n\u251c\u2500\u2500 roles\/\n\u251c\u2500\u2500 files\/\n\u251c\u2500\u2500 templates\/\n\u2514\u2500\u2500 site.yml<\/code><\/span><\/pre>\n\n\n<ul class=\"wp-block-list\"><li>Use pull requests for every change.<\/li><li>Run lint\/syntax checks in CI before merge.<\/li><li>Promote the same reviewed change from dev to stage to production.<\/li><li>Record execution logs for audit and incident review.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Best practices and common pitfalls<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Prefer small, reversible changes:<\/strong> large batches increase blast radius.<\/li><li><strong>Avoid snowflake servers:<\/strong> if a manual fix is needed, codify it immediately.<\/li><li><strong>Separate secrets from code:<\/strong> use a proper secrets manager or encrypted variable strategy.<\/li><li><strong>Design for drift detection:<\/strong> schedule regular convergence checks, not only one-time setup.<\/li><li><strong>Test in lower environments first:<\/strong> validate roles and modules before production rollout.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Done well, configuration management becomes a repeatable control plane for system state: consistent, reviewable, and automation-friendly.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This guide explains how configuration management works in modern DevOps teams, compares common tools, and shows a practical Ansible example. It also preserves the original SlideShare reference from the legacy post.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[2],"tags":[],"class_list":["post-224","post","type-post","status-publish","format-standard","hentry","category-uncategorised"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/224","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=224"}],"version-history":[{"count":2,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/224\/revisions"}],"predecessor-version":[{"id":79054,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/224\/revisions\/79054"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=224"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=224"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=224"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}