| |

LFCA 91 🐧 What Configuration Management Is

You have provisioned a server. It exists. It has an operating system, a network interface, and a disk. But it is not ready to run your application. It needs packages installed, configuration files written, services started, and permissions set. The work of turning a freshly provisioned server into a functioning part of your infrastructure is configuration management.

Configuration management is the automated, version-controlled management of application settings and the environments that support them . It is the layer that comes after provisioning. Infrastructure as Code creates the virtual machine. Configuration management installs the software, configures the settings, and manages the ongoing changes on that machine . The two practices overlap, and some teams use “Infrastructure as Code” to cover both. But distinguishing them clarifies responsibilities: infrastructure engineers handle provisioning, and application teams handle configuration .

Key point: Configuration management treats configuration as code. The configuration files are stored in version control, reviewed before changes are applied, and deployed through automated pipelines . Adding a firewall rule becomes: edit the configuration file, commit the change, run the pipeline, and the rule applies automatically. No remote desktop sessions. No manual changes that get forgotten or done inconsistently .


Why configuration management matters

Manual configuration does not scale. It works for one server. It fails for a fleet.

The drift problem. A developer logs into a server and changes a setting. The change is not documented. The next server is configured differently. Over time, the environments diverge. The development environment behaves differently from production. The bug that only appears in production is caused by a configuration difference that no one remembers making . Configuration management eliminates drift by making the configuration file the source of truth. The tool ensures every server matches the file .

The reproducibility problem. A new server needs to be configured. With manual configuration, the administrator follows a runbook. The runbook is incomplete. The gaps are filled with knowledge that lives in the administrator’s head. When the administrator is unavailable, the knowledge is unavailable . Configuration as code solves this. The configuration file is the complete, executable documentation. Anyone can run the tool and get the same result.

The audit problem. A change is made to the infrastructure. Who made it? When? Why? With manual configuration, the answers are in the administrator’s memory. With configuration as code, the answers are in the commit history. The version control system records every change .

The speed problem. A new server takes hours to configure manually. With configuration management, the tool applies the configuration in minutes. The speed is a side effect of the automation. The consistency is the point.

The trade-off. Configuration management requires learning a tool. Ansible, Puppet, Chef, and Salt each have their own syntax, their own model, and their own ecosystem . The learning curve is real. But the alternative — manual configuration — is a curve that never flattens, and a risk that grows with every server added.


a. Configuration as Code

Configuration as code is the practice of storing configuration files in version control. The files describe the desired state of the system. The tool reads the files and applies the changes needed to reach that state .

The workflow mirrors the software development workflow. The configuration is written, committed, reviewed, and deployed through an automated pipeline. The configuration file is the documentation. The commit history is the audit log .

The comparison between manual configuration and configuration as code is stark. Manual configuration is error-prone, hard to reproduce, and documentation becomes outdated. Configuration as code is reliable, reproducible, and self-documenting. The configuration files are the documentation .

AspectManual ConfigurationConfiguration as Code
ReproducibilityHard to reproduceSame code, same result
Error rateHuman errorAutomation eliminates error
DocumentationBecomes outdatedConfiguration is the documentation
Deployment speedSlow, manualFast, automated
Audit trailIn memoryIn version control
DriftAccumulatesDetected and corrected

b. The Tool Landscape

Four tools dominate configuration management: Ansible, Puppet, Chef, and Salt . Each has a different architecture, a different language, and a different philosophy.

Ansible is agentless. It uses SSH to connect to managed nodes and does not require software to be installed on them . The configuration is written in YAML playbooks, which are human-readable and read like documentation . Ansible is known for its simplicity and ease of use . It is the tool recommended for beginners and for teams that value low maintenance overhead .

Puppet uses a master-agent architecture. A Puppet master server compiles manifests into catalogs and pushes them to agents on each node . The configuration is written in Puppet’s DSL, which is based on Ruby . Puppet is mature and has strong reporting and monitoring capabilities. It is system-administrator oriented .

Chef also uses a master-agent architecture. The configuration is written in Cookbooks and Recipes, using a Ruby-based DSL . Chef is known for its flexibility and detailed control, but it has a steeper learning curve than Ansible .

Salt is designed for speed and scalability. It uses an event-driven architecture and a Python-based language . Salt can operate with or without agents . It is the fastest of the four tools, but it has a smaller ecosystem and a steeper learning curve .

The choice depends on the organization’s needs. Ansible is the simplest and the most popular for new projects. Puppet and Chef are mature and suited for large, complex environments. Salt is the performance choice .


c. The Core Principles

Configuration management tools share a set of principles that make them work.

Idempotency is the property that an operation produces the same result regardless of how many times it is executed. An Ansible playbook can be run over and over again, and it will not introduce undesirable side effects. If the system is already in the desired state, the tool does nothing . This is what makes configuration management safe. A deployment that fails halfway can be re-run. The tool completes the configuration without duplicating the work that was already done .

Declarative specification means the configuration describes the desired end state, not the steps to reach it. The tool figures out the steps. The administrator describes what the system should look like . This is different from a shell script that executes a sequence of commands. The shell script is imperative. The configuration file is declarative.

The inventory is the list of managed nodes. Ansible uses an inventory file that groups hosts by function . Puppet, Chef, and Salt use similar mechanisms. The inventory tells the tool which nodes to configure .

The playbook, manifest, or cookbook is the configuration file. Ansible calls them playbooks. Puppet calls them manifests. Chef calls them cookbooks. Salt calls them states. The name is different, but the purpose is the same: to describe the desired state of the system .


Complete Example Session

This session demonstrates configuration management with an Ansible playbook.

# ============================================
# PART 1: THE INVENTORY
# ============================================

# inventory.ini
[webservers]
web1 ansible_host=192.168.1.10
web2 ansible_host=192.168.1.11
web3 ansible_host=192.168.1.12

[databases]
db1 ansible_host=192.168.1.20

# The inventory groups the hosts by function.
# Ansible connects to each host via SSH.

# ============================================
# PART 2: THE PLAYBOOK
# ============================================

# playbook.yml
---
- name: Configure web servers
  hosts: webservers
  become: yes

  tasks:
    - name: Install nginx
      ansible.builtin.apt:
        name: nginx
        state: present

    - name: Start nginx
      ansible.builtin.service:
        name: nginx
        state: started
        enabled: yes

    - name: Copy configuration
      ansible.builtin.template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      notify: Restart nginx

  handlers:
    - name: Restart nginx
      ansible.builtin.service:
        name: nginx
        state: restarted

# The playbook declares the desired state.
# The tasks are idempotent.
# Running the playbook twice produces the same result.

# ============================================
# PART 3: THE RUN
# ============================================

# ansible-playbook -i inventory.ini playbook.yml

# Output:
# PLAY [Configure web servers] ***************************
# TASK [Install nginx] ***********************************
# ok: [web1]
# ok: [web2]
# ok: [web3]
# TASK [Start nginx] *************************************
# ok: [web1]
# ok: [web2]
# ok: [web3]
# TASK [Copy configuration] ******************************
# changed: [web1]
# changed: [web2]
# changed: [web3]
# RUNNING HANDLER [Restart nginx] ************************
# changed: [web1]
# changed: [web2]
# changed: [web3]

# The "ok" status means no change was needed.
# The "changed" status means the task modified the system.

# ============================================
# PART 4: THE SECOND RUN
# ============================================

# ansible-playbook -i inventory.ini playbook.yml

# Output:
# PLAY [Configure web servers] ***************************
# TASK [Install nginx] ***********************************
# ok: [web1]
# ok: [web2]
# ok: [web3]
# TASK [Start nginx] *************************************
# ok: [web1]
# ok: [web2]
# ok: [web3]
# TASK [Copy configuration] ******************************
# ok: [web1]
# ok: [web2]
# ok: [web3]

# No "changed" statuses.
# The system is already in the desired state.
# The playbook is idempotent.

# ============================================
# PART 5: THE CONFIGURATION FILE
# ============================================

# ansible.cfg
[defaults]
inventory = ./inventory.ini
remote_user = ansible
host_key_checking = False
retry_files_enabled = False

# The configuration file controls Ansible's behavior.
# It is stored in version control.

# ============================================
# PART 6: THE VERSION CONTROL
# ============================================

# git add inventory.ini playbook.yml ansible.cfg
# git commit -m "Add web server configuration"
# git push origin main

# The configuration is stored in Git.
# The commit history is the audit log.
# The configuration is reviewed before it is applied.

# ============================================
# PART 7: THE DRIFT DETECTION
# ============================================

# Someone manually changes the nginx configuration.
# ssh web1
# vim /etc/nginx/nginx.conf
# (makes a change)

# Run the playbook again.
# ansible-playbook -i inventory.ini playbook.yml

# Output:
# TASK [Copy configuration] ******************************
# changed: [web1]

# The playbook detects the drift and corrects it.
# The configuration file is the source of truth.

# ============================================
# PART 8: THE IDEMPOTENCY
# ============================================

# The same playbook can be run repeatedly.
# It does not duplicate the work.
# It does not restart the service if nothing changed.
# It does not fail if the package is already installed.

# ============================================
# PART 9: THE CONFIGURATION MANAGEMENT PLAN
# ============================================

# A configuration management plan documents:
# - The configuration items
# - The roles and responsibilities
# - The change control process
# - The status accounting
# - The audits and reviews 

# The plan is tailored to the organization's needs.
# It ensures the configuration management process is consistent.

# ============================================
# PART 10: THE PRINCIPLES
# ============================================

# Idempotency: same operation, same result
# Declarative: describe the desired state
# Version-controlled: configuration in Git
# Automated: applied through pipelines
# Auditable: commit history is the record
# Reproducible: same configuration, same result

The ten parts cover the inventory, the playbook, the run, the second run, the configuration file, the version control, the drift detection, the idempotency, the configuration management plan, and the principles.


Quick Reference

The Configuration Management Tools

ToolArchitectureLanguageApproach
AnsibleAgentless (SSH)YAMLDeclarative
PuppetMaster-AgentPuppet DSL (Ruby)Declarative
ChefMaster-AgentRuby DSLImperative
SaltMaster-Minion/AgentlessPython/YAMLMixed

The Core Principles

PrincipleDescription
IdempotencySame operation, same result
DeclarativeDescribe the desired state
Version controlConfiguration in Git
AutomationApplied through pipelines
AuditabilityCommit history is the record

The Comparison

AspectManualConfiguration as Code
ReproducibilityHardEasy
Error rateHighLow
DocumentationOutdatedThe configuration
SpeedSlowFast
DriftAccumulatesCorrected

The Configuration Items

ItemPurpose
InventoryList of managed hosts
Playbook/ManifestDesired state definition
Configuration fileTool behavior
Version controlAudit and review

Best Practices

✅ Do This:

# Store configuration in version control
# git commit -m "Add web server configuration"                    # ✅
# Use idempotent modules
- name: Install nginx
  ansible.builtin.apt: { name: nginx, state: present }            # ✅
# Use handlers for service restarts
notify: Restart nginx                                             # ✅
# Test in a non-production environment first
ansible-playbook -i staging.ini playbook.yml                     # ✅

❌ Don’t Do This:

# Don't configure servers manually
ssh web1 "apt install nginx"                                      # ❌
# Don't use imperative shell commands when a module exists
- shell: apt install nginx                                        # ❌
# Don't hardcode secrets in playbooks
password: "hardcoded"                                             # ❌
# Don't skip version control
# Configuration files should be in Git.                          # ❌

Common Pitfalls

PitfallWhy It HappensFix
Drift accumulatesManual changesRe-apply the playbook
Playbook not idempotentShell commands usedUse modules
Secrets in playbookHardcoded valuesUse a vault
Slow applySequential executionUse strategies or forks
Configuration outdatedNo version controlStore in Git

Real-World Examples

1. Ansible Playbook

- name: Configure web servers
  hosts: webservers
  tasks:
    - name: Install nginx
      ansible.builtin.apt: { name: nginx, state: present }

2. Puppet Manifest

package { 'nginx':
  ensure => installed,
}
service { 'nginx':
  ensure => running,
}

3. Chef Recipe

package 'nginx' do
  action :install
end
service 'nginx' do
  action [:enable, :start]
end

4. Salt State

nginx:
  pkg.installed: []
  service.running:
    - enable: True

5. Idempotency

- name: Ensure nginx is installed
  apt: { name: nginx, state: present }

6. Drift Detection

ansible-playbook -i inventory.ini playbook.yml --check

7. Version Control

git add playbook.yml && git commit -m "Add nginx config"

8. Inventory

[webservers]
web1 ansible_host=192.168.1.10

9. Configuration File

[defaults]
inventory = ./inventory.ini

10. Run

ansible-playbook -i inventory.ini playbook.yml

Visual

The Configuration Management Layer

┌──────────────────────────────────────────────┐
│  INFRASTRUCTURE AS CODE                      │
│    └─ Provisions the server                  │
│       (VM, network, storage)                 │
│                                              │
│  CONFIGURATION MANAGEMENT                    │
│    └─ Configures the server                  │
│       (packages, files, services)            │
│                                              │
│  The two layers are complementary.           │
│  IaC creates. Configuration management runs. │
│                                              │
└──────────────────────────────────────────────┘

The Idempotency Loop

┌──────────────────────────────────────────────┐
│  IDEMPOTENCY                                 │
│                                              │
│  Run 1: Install nginx ──> changed            │
│  Run 2: Install nginx ──> ok (no change)     │
│  Run 3: Install nginx ──> ok (no change)     │
│                                              │
│  The result is the same.                     │
│  The operation is safe to repeat.            │
│                                              │
└──────────────────────────────────────────────┘

The Configuration as Code Workflow

┌──────────────────────────────────────────────┐
│  CONFIGURATION AS CODE                       │
│                                              │
│  Write ──> Commit ──> Review ──> Apply       │
│       │                                      │
│       ▼                                      │
│  Version control records the change          │
│       │                                      │
│       ▼                                      │
│  Pipeline applies the configuration          │
│                                              │
└──────────────────────────────────────────────┘

The Drift Detection

┌──────────────────────────────────────────────┐
│  DRIFT DETECTION                             │
│                                              │
│  Configuration file: nginx.conf (expected)   │
│  Server:              nginx.conf (modified)  │
│                                              │
│  Run the playbook:                           │
│    └─ Detects the difference                 │
│    └─ Restores the expected configuration    │
│                                              │
│  The configuration file is the source of truth│
│                                              │
└──────────────────────────────────────────────┘

Summary

ItemValue
Configuration managementAutomated, version-controlled management of settings
Configuration as codeStoring configuration in version control
IaC vs CMIaC provisions, CM configures
ToolsAnsible, Puppet, Chef, Salt
IdempotencySame operation, same result
DeclarativeDescribe the desired state
DriftConfiguration divergence
AuditCommit history is the record
LFCA weightDevOps Fundamentals, 12–16%

Key takeaways:

  • Configuration management is the automated, version-controlled management of application settings and the environments that support them. It focuses on configuring resources after they are created. Infrastructure as Code creates the virtual machine. Configuration management installs the software, configures the settings, and manages the ongoing changes .
  • Configuration as code treats configuration files like source code. The files are stored in version control, reviewed before changes are applied, and deployed through automated pipelines. The configuration file is the documentation. The commit history is the audit log .
  • The core principle is idempotency. An operation produces the same result regardless of how many times it is executed. A playbook can be run repeatedly without duplicating work or causing errors. If the system is already in the desired state, the tool does nothing .
  • Four tools dominate the configuration management landscape. Ansible is agentless and uses YAML. Puppet uses a master-agent architecture and a Ruby-based DSL. Chef uses a master-agent architecture and a Ruby DSL. Salt is designed for speed and uses Python .
  • Ansible is the simplest and the most popular for new projects. It requires no agent on the managed nodes. It uses SSH. Its playbooks are human-readable YAML. It is the recommended starting point for teams new to configuration management .
  • Configuration management eliminates drift. The configuration file is the source of truth. The tool ensures every server matches the file. When a manual change is made, the next run of the tool detects the drift and corrects it .
  • The LFCA exam tests the concepts, not the tools. The exam expects you to understand what configuration management is, why it matters, and how it differs from Infrastructure as Code. The specific tools are secondary .

Remember: Configuration management is the layer that turns a provisioned server into a functioning part of the infrastructure. It treats configuration as code. The files are stored in version control. The tool applies them idempotently. The result is reproducible, auditable, and consistent. Ansible, Puppet, Chef, and Salt are the tools. Idempotency is the principle. Configuration as code is the practice.


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!