DevOps

Chapter 7
Infrastructure as Code and Configuration Management

Bachelors Program in Computer Applications
DevOps   •   Bachelor

Infrastructure as Code and Configuration Management

Introduction and Context

Modern software systems depend on more than application source code. They require virtual networks, compute instances, containers, databases, identity policies, monitoring, certificates, operating-system packages, and environment-specific settings. When these resources are created manually, infrastructure becomes difficult to reproduce, audit, test, and recover. Infrastructure as Code (IaC) addresses this problem by representing infrastructure in machine-readable files that can be versioned, reviewed, tested, and executed automatically.

Configuration management complements IaC. IaC commonly establishes the resources on which a system runs, while configuration management installs software, applies operating-system settings, manages services, and maintains desired runtime conditions. Together they support repeatable delivery across development, testing, staging, and production environments.

The central principle is that infrastructure should be treated as an engineered product rather than as an undocumented collection of manual actions. A reliable infrastructure process makes the desired state explicit, applies changes consistently, records who approved them, and provides a controlled method of rollback or recovery.

Learning Objectives

After studying this chapter, a learner should be able to:

  • explain the purpose and architecture of Infrastructure as Code;
  • distinguish declarative and imperative provisioning approaches;
  • compare provisioning tools with configuration-management tools;
  • apply immutable-infrastructure principles;
  • manage secrets and sensitive configuration safely;
  • explain state files, drift, locking, and recovery;
  • use policy as code to enforce governance;
  • design environment-consistent delivery workflows;
  • evaluate the operational, security, and organizational limitations of IaC.

1. Foundations of Infrastructure as Code

Infrastructure as Code is the practice of defining and managing infrastructure through code or structured configuration files instead of relying primarily on manual console operations. The files may describe cloud resources, network topology, access controls, container platforms, or machine configuration.

A typical IaC workflow contains the following stages:

  1. Authoring: engineers write infrastructure definitions.
  2. Version control: definitions are committed to a repository.
  3. Validation: syntax, formatting, security, and policy checks are performed.
  4. Planning: the tool calculates the proposed change.
  5. Review and approval: people inspect the planned change.
  6. Application: approved changes are applied to the target environment.
  7. Observation: monitoring confirms that the resulting system behaves correctly.
  8. Reconciliation: drift or failures are corrected.

The desired result is not merely automation. It is controlled, repeatable automation with traceability.

Important terminology

  • Resource: an infrastructure object such as a virtual machine, subnet, database, or security rule.
  • Desired state: the condition an engineer declares or specifies.
  • Actual state: the condition currently present in the environment.
  • Drift: divergence between desired state and actual state.
  • Provisioning: creation or allocation of infrastructure resources.
  • Configuration management: installation and maintenance of software and system settings.
  • Idempotence: the property that applying the same operation repeatedly produces the same intended result after convergence.
  • Reconciliation: comparing desired and actual state and taking corrective action.
  • Configuration drift: unintended change caused by manual operations, uncontrolled automation, or external systems.

2. Declarative and Imperative Approaches

Declarative infrastructure

A declarative specification describes the desired end state without prescribing every operational step. For example, a declaration may state that a network must contain two private subnets and that a database must be encrypted and accessible only from an application security group. The tool determines the sequence required to create or modify those resources.

Declarative systems are useful because they express intent, support comparison between desired and actual state, and often provide a change plan before execution. Examples include Terraform, OpenTofu, AWS CloudFormation, Azure Resource Manager templates, Kubernetes manifests, and many policy engines.

A simplified declarative example is:

service:
  name: payments-api
  replicas: 3
  image: registry.example/payments:2.4.1
  network:
    public: false

The exact syntax differs by tool. The important idea is that the file describes what should exist rather than a complete sequence of shell commands.

Imperative infrastructure

An imperative approach specifies the actions to execute. A script might create a network, create a server, install a package, write a configuration file, and restart a service. Shell scripts, Python programs, cloud-provider SDK calls, and command-line sequences are common imperative techniques.

Imperative automation is flexible and can express complex procedural logic. It is especially useful for migrations, one-time operations, custom integrations, and tasks for which no suitable declarative resource exists. However, imperative scripts can become difficult to reason about when they are rerun, partially fail, or encounter resources created outside the script.

Comparison

CharacteristicDeclarative approachImperative approach
Main questionWhat should exist?What steps should run?
State comparisonUsually built inMust be designed or scripted
RepeatabilityGenerally strongDepends on idempotent implementation
FlexibilityConstrained by provider/modelHigh
Typical riskIncorrect dependency or state interpretationOrdering, duplication, and partial failure
Suitable usesStandard infrastructure and desired-state systemsCustom workflows and migrations

The approaches are not mutually exclusive. A mature platform may use declarative provisioning for networks and databases, configuration management for operating systems, and imperative scripts for data migration.

3. Provisioning and Configuration Management

Provisioning creates the infrastructure substrate. Configuration management prepares that substrate for operation. The boundary is not absolute, but the following distinction is useful:

  • IaC provisioning creates a virtual network, load balancer, compute resource, managed database, and identity roles.
  • Configuration management installs packages, creates users, writes service configuration, applies hardening settings, and starts services.

Tools such as Ansible, Puppet, Chef, and Salt are commonly associated with configuration management. They may be agentless or agent-based and may use push or pull models.

Push and pull models

In a push model, a central control process connects to target machines and applies configuration. This can be simple for small fleets but requires network access and suitable credentials.

In a pull model, an agent on each target periodically retrieves its configuration from a central service. Pull models can operate more effectively across changing networks, but they introduce agent lifecycle, scheduling, and control-plane dependencies.

Idempotence in configuration management

Consider a poor script:

echo "appuser:password" >> /etc/appusers

Every execution appends another line. It is not idempotent. A better operation checks whether the desired entry already exists and changes the file only when necessary. Configuration tools usually provide resources such as “user,” “package,” “file,” and “service” that implement this reasoning.

Idempotence does not mean that every operation is harmless to repeat. Database schema migrations, data deletion, and certificate replacement require explicit safeguards. Engineers must identify operations that are inherently stateful or irreversible.

4. Infrastructure Lifecycle and Dependency Management

Infrastructure resources have dependencies. A database may depend on a subnet, a server may depend on an identity role, and a load balancer may depend on target registration. IaC tools construct a dependency graph from explicit references or declared relationships.

A sound lifecycle includes:

  • Creation: allocate resources in dependency order.
  • Update: modify properties while preserving service continuity where possible.
  • Replacement: destroy and recreate resources when in-place modification is unsafe or unsupported.
  • Destruction: remove resources deliberately, with protection for critical assets.
  • Recovery: restore resources and data after failure.

Replacement deserves particular attention. Changing an immutable machine image may create a new instance rather than modifying the old instance. This can reduce configuration drift, but it requires health checks, traffic management, and data persistence design.

Lifecycle controls should address accidental destruction, retention of databases, dependency ordering, and maintenance windows. A successful plan is not automatically a safe plan; engineers must understand the operational consequences of each action.

5. Immutable Infrastructure

Mutable infrastructure is changed in place. An administrator may log into a server, install a patch, edit a file, and restart a process. Over time, servers that began identically may become different.

Immutable infrastructure treats deployed instances as replaceable artifacts. Instead of modifying a running server extensively, the team builds a new machine image or container image, tests it, and replaces the old instance. This approach makes versioning clearer and reduces configuration drift.

A common immutable workflow is:

  1. Build an image from a versioned definition.
  2. Apply operating-system updates and application dependencies.
  3. Run security and functional tests.
  4. Publish the image with a unique version identifier.
  5. Deploy new instances from that image.
  6. Shift traffic gradually or at a controlled cutover.
  7. Retain the previous version for rollback.

Immutability does not mean that no state exists. Databases, object stores, queues, and user-generated files must be designed as durable external state. The principle mainly applies to replaceable compute and service instances.

Blue-green deployment maintains two environments: the currently active blue environment and the candidate green environment. Traffic can be shifted to green after validation. Canary deployment sends a small percentage of traffic to the new version before broader rollout. Both techniques depend on health monitoring and a rapid rollback mechanism.

6. State Management

Some IaC tools maintain a state representation that maps configuration resources to real infrastructure objects. State helps the tool determine what already exists and what changes are required. It may include resource identifiers, attributes, dependencies, and metadata.

State management introduces several responsibilities:

  • store state in a durable and access-controlled location;
  • enable locking so concurrent changes do not corrupt state;
  • encrypt state when it contains sensitive attributes;
  • back up state and test restoration;
  • restrict who can read or modify it;
  • avoid manually editing state unless documented recovery procedures require it.

A remote state backend is normally preferable for team environments because it supports shared access, locking, versioning, and audit logging. A local state file can be acceptable for experimentation but is fragile for collaborative or production work.

Drift detection

Drift occurs when actual infrastructure changes independently of the IaC workflow. Examples include a manually opened firewall rule, a changed instance size, or deletion of a resource from a cloud console. A refresh or plan operation may reveal the difference.

Teams must decide how to respond to drift:

  • restore the declared configuration;
  • import and formalize the legitimate change;
  • modify the source definition and review it;
  • investigate whether unauthorized activity occurred.

Silently accepting drift undermines the reliability of IaC. Conversely, automatically overwriting every external change can cause outages. Detection, classification, and approved reconciliation are safer than blind correction.

7. Secrets and Sensitive Configuration

Secrets include passwords, private keys, access tokens, database credentials, signing keys, and encryption material. They require stronger controls than ordinary configuration.

A secret should not be embedded in source code, committed to a repository, printed in build logs, or placed unencrypted in a state file. Instead, applications should retrieve secrets from a dedicated secret-management system or an appropriately protected runtime mechanism.

Good practices include:

  • use a secret manager or encrypted parameter store;
  • grant access according to least privilege;
  • separate secret creation from ordinary infrastructure code;
  • rotate credentials regularly and after suspected exposure;
  • avoid passing secrets through command-line arguments where process listings may reveal them;
  • redact values from logs and error messages;
  • audit access and investigate unusual retrieval patterns;
  • use short-lived credentials where practical.

Encryption at rest is necessary but not sufficient. A user who can decrypt and read a secret still requires authorization. Secret confidentiality, integrity, availability, and rotation must all be considered.

Configuration also includes non-secret values such as region, feature flags, connection endpoints, and resource sizing. Environment-specific values should be explicit and validated, while common definitions should be reused. Reuse must not become uncontrolled inheritance that makes the final configuration impossible to understand.

8. Policy as Code

Policy as code expresses governance and security requirements in machine-evaluable form. Policies can prevent noncompliant infrastructure from being planned or deployed.

Examples include:

  • storage must be encrypted;
  • public IP addresses are prohibited for internal databases;
  • mandatory cost-center tags must be present;
  • only approved container registries may be used;
  • production changes require an approved pipeline;
  • resources may be created only in permitted regions.

Policy can operate at different points: during code review, during plan generation, at deployment admission, or continuously against running resources. Preventive controls block violations before deployment; detective controls identify violations after deployment.

A policy should be specific enough to evaluate and accompanied by an understandable explanation. Poorly designed policies can block legitimate work, encourage bypasses, or create alert fatigue. Exceptions should be time-limited, documented, approved, and reviewed.

9. Environment Consistency and Reuse

Development, testing, staging, and production environments should be similar enough that behavior in one provides useful evidence about another. They do not need identical scale or cost. A small test database may be appropriate, but differences in operating system, networking, authentication, or service versions can create misleading results.

Useful practices include:

  • use the same module or template version across environments;
  • pin provider, plugin, image, and dependency versions;
  • define environment differences as explicit variables;
  • use automated validation in every environment;
  • maintain representative test data without exposing personal information;
  • document intentional differences such as capacity and redundancy;
  • avoid environment-specific manual fixes.

Reusable modules should have clear inputs, outputs, naming conventions, versioning, and documentation. A module should encapsulate a coherent capability, such as a private application network or an encrypted database, rather than merely hide arbitrary complexity.

10. A Practical Workflow

A professional IaC repository commonly contains infrastructure definitions, modules, environment configuration, policy tests, documentation, and pipeline definitions. A pull request may follow this sequence:

  1. The engineer changes the infrastructure definition.
  2. Formatting and static validation run automatically.
  3. Security scanners check for exposed credentials and insecure settings.
  4. A plan is generated and stored as a review artifact.
  5. Reviewers inspect both source changes and planned actions.
  6. An approved pipeline applies the exact reviewed plan.
  7. Post-deployment tests verify reachability, security, and service health.
  8. Monitoring and drift detection continue after deployment.

The plan should be treated as an important technical artifact. Reviewers should ask whether a resource will be replaced, whether data may be lost, whether network exposure changes, and whether cost or capacity changes are justified.

Worked example: evaluating a change

Suppose an application server is changed from image version 1.8 to 1.9. The plan indicates that the server will be replaced, a new instance will be created, and the old instance will be removed after health checks pass.

The correct review is not simply “the image changed.” The team should verify:

  • image 1.9 passed vulnerability and functional tests;
  • the instance has no irreplaceable local data;
  • the load balancer waits for a healthy status;
  • the old instance remains available during transition;
  • rollback can restore image 1.8;
  • monitoring distinguishes application failure from infrastructure failure.

This example demonstrates why infrastructure review requires operational reasoning, not only syntax checking.

11. Illustrative Case Study: Online Learning Platform

Background

An illustrative university online-learning platform runs a web application, a background job service, a managed relational database, object storage, and a monitoring system. Initially, administrators created resources manually in a cloud console. Development and production used different operating-system images and package versions.

Problem

Deployments were slow and inconsistent. A security patch applied to one production server was not applied to another. A manually modified firewall rule was not documented. During an incident, the team could not reliably reconstruct the infrastructure or identify the exact configuration of a failed server.

Analysis

The main causes were undocumented procedures, mutable servers, shared administrator credentials, and the absence of a reviewed state-management process. The organization also stored a database password in a deployment script.

Approach and solution

The team introduced the following design:

  • declarative definitions for networks, identity roles, databases, storage, and monitoring;
  • versioned modules shared by development, staging, and production;
  • an image-building pipeline for the operating system and application runtime;
  • immutable application instances behind a load balancer;
  • a managed secret store with automatic credential rotation;
  • remote, encrypted state with locking and versioned backups;
  • policy checks requiring encryption, private databases, approved regions, and ownership tags;
  • pull-request review and an approval-controlled production pipeline;
  • drift detection scheduled daily;
  • synthetic tests after deployment.

Environment differences were limited mainly to scale, retention, and redundancy. Production used multiple availability zones, while development used a smaller topology.

Outcome

The platform achieved reproducible environment creation and reduced the number of configuration differences between stages. New instances could be replaced rather than repaired manually. Auditors could trace infrastructure changes to reviewed commits and pipeline executions. The organization also improved incident recovery because infrastructure definitions and image versions were available in source control.

The solution did not eliminate all risk. Database migrations still required careful procedures, secrets remained sensitive, and a faulty module could affect several environments. Therefore, testing, staged rollout, backups, and human review remained essential.

Learning points

  1. IaC provides repeatability only when definitions are versioned, reviewed, and actually used.
  2. Immutable compute does not remove the need to protect durable data.
  3. State is operationally critical and must be secured and backed up.
  4. Policy as code converts selected governance requirements into enforceable controls.
  5. Environment consistency is a design goal, not a claim that every environment must have identical capacity.

12. Challenges, Limitations, and Governance

IaC can amplify errors. A wrong network rule or destructive resource change may be applied to many environments quickly. Automation therefore increases the importance of testing, approval boundaries, and blast-radius control.

Other limitations include:

  • provider APIs may behave differently over time;
  • state can become inconsistent or inaccessible;
  • complex modules may hide important behavior;
  • secrets may leak through logs, state, or debug output;
  • external resources may not be fully represented;
  • teams may develop excessive dependence on one provider;
  • policy rules may become outdated;
  • automation can reproduce an insecure design very efficiently.

Governance should establish ownership, repository protections, approval requirements, emergency-change procedures, retention rules, and auditability. Production credentials should be separated from developer credentials, and pipelines should use narrowly scoped identities.

Ethically and legally, infrastructure teams must protect personal data, respect data-residency requirements, maintain accessibility and availability, and avoid collecting unnecessary telemetry. Infrastructure definitions can encode surveillance, access restrictions, or retention policies; these choices deserve review beyond purely technical criteria.

13. Contemporary Developments

Cloud platforms increasingly offer managed infrastructure, serverless services, Kubernetes operators, and declarative control planes. GitOps extends IaC by using a version-control repository as the authoritative source for desired system state, with an agent continuously reconciling the running environment.

Software supply-chain security is also becoming central. Infrastructure pipelines should verify provider plugins, modules, container images, and build artifacts. Provenance records, signed artifacts, dependency pinning, and vulnerability scanning reduce the risk of compromised dependencies.

Artificial intelligence can assist with template generation, policy explanation, anomaly detection, and remediation suggestions. However, generated infrastructure must be reviewed like human-authored infrastructure. AI systems may produce insecure public exposure, excessive permissions, incorrect dependencies, or fabricated provider settings. Human accountability, testing, and approval cannot be delegated merely because code was machine-generated.

Best Practices Checklist

  • Store infrastructure definitions in version control.
  • Separate reusable modules from environment-specific values.
  • Prefer declarative definitions for standard resources.
  • Make imperative operations explicit, tested, and safe to repeat where possible.
  • Pin versions and review upgrades.
  • Generate and inspect plans before production changes.
  • Secure, lock, back up, and audit state.
  • Keep secrets out of source code and logs.
  • Use least privilege for users and pipelines.
  • Build immutable images for replaceable compute.
  • Protect durable data with backups and tested recovery.
  • Enforce security and governance through policy as code.
  • Detect and investigate drift.
  • Test modules and complete environments.
  • Design rollback and failure handling before deployment.

Chapter Summary

Infrastructure as Code represents infrastructure in versioned, machine-readable definitions. Declarative approaches describe desired state and are effective for standard provisioning, while imperative approaches describe actions and remain valuable for custom workflows and migrations. Configuration management maintains software and system settings after or alongside provisioning, and idempotence helps repeated execution converge safely.

Immutable infrastructure reduces drift by replacing tested images instead of modifying servers indefinitely, but durable data still requires independent protection. State management enables tools to map definitions to real resources and therefore demands locking, encryption, backups, access control, and drift handling. Secrets must be isolated from source code and logs and managed through controlled, auditable systems. Policy as code makes selected security, cost, and compliance rules enforceable. Finally, environment consistency, reviewable plans, staged deployment, monitoring, and governance transform automation into dependable professional practice.

Key Terms

Infrastructure as Code: Managing infrastructure through versioned, machine-readable definitions.

Declarative approach: Describing the desired end state rather than every execution step.

Imperative approach: Specifying the sequence of actions to perform.

Provisioning: Creating or allocating infrastructure resources.

Configuration management: Maintaining software, operating-system, and service settings.

Desired state: The condition an infrastructure definition requires.

Actual state: The condition currently present in an environment.

Drift: Difference between desired and actual state.

Idempotence: Ability to apply an operation repeatedly without unwanted cumulative effects.

Immutable infrastructure: Replaceable infrastructure instances that are not routinely modified in place.

State file: A record used to map IaC resources to deployed objects and attributes.

State locking: Preventing simultaneous operations from corrupting shared state.

Secret: Sensitive information such as a password, token, or private key.

Policy as code: Machine-evaluable rules governing infrastructure and deployments.

Module: A reusable, encapsulated infrastructure definition.

Blue-green deployment: Operating old and new environments concurrently to enable controlled traffic switching.

Canary deployment: Releasing a new version to a limited portion of users or traffic first.

Reconciliation: Comparing desired and actual state and correcting differences.

GitOps: A model in which version control represents desired state and automated agents reconcile the running system.

Least privilege: Granting only the permissions required for a task.

Review Questions

Short Answer Questions

  1. What is Infrastructure as Code, and why is version control important for it?
  2. Distinguish declarative and imperative infrastructure approaches.
  3. Define configuration drift and give one example.
  4. Why should state files be protected and backed up?
  5. What is the purpose of policy as code?

Long Answer Questions

  1. Explain how provisioning and configuration management complement each other in a production environment.
  2. Compare mutable and immutable infrastructure, including their advantages and limitations.
  3. Describe a secure workflow for managing secrets in an IaC-based delivery pipeline.
  4. Explain how a team can maintain consistency across development, testing, staging, and production.
  5. Discuss the governance controls required when infrastructure changes are automated.

Analytical / Application Questions

  1. A team discovers that a production firewall rule was changed manually and is absent from the repository. Analyze the possible responses and recommend a safe reconciliation process.
  2. An IaC plan proposes replacing a database instance because its storage configuration changed. What technical, operational, and governance questions should be answered before approval?
  3. Design an IaC and configuration-management strategy for a university examination system that requires high availability, protected student data, auditable changes, and rapid rollback.

Multiple Choice Questions with Answers

Question 1

Which statement best describes a declarative IaC approach?

A. It specifies the desired end state and lets the tool determine actions.

B. It requires an administrator to execute every command manually.

C. It always modifies existing resources in place.

D. It cannot represent dependencies between resources.

Correct Answer: A. It specifies the desired end state and lets the tool determine actions.

Question 2

What is configuration drift?

A. A planned upgrade recorded in version control

B. A difference between desired infrastructure and actual infrastructure

C. A method for encrypting state files

D. A deployment strategy using two environments

Correct Answer: B. A difference between desired infrastructure and actual infrastructure

Question 3

Which practice is most appropriate for production IaC state?

A. Store it in an unprotected local folder shared by email

B. Commit plaintext credentials inside it

C. Use controlled remote storage with locking, encryption, and backups

D. Delete it after every deployment

Correct Answer: C. Use controlled remote storage with locking, encryption, and backups

Question 4

Which example represents immutable infrastructure?

A. Logging into a server weekly to apply undocumented changes

B. Replacing a tested instance image with a newly built version

C. Allowing each developer to change production packages

D. Editing a running container manually and never recording the change

Correct Answer: B. Replacing a tested instance image with a newly built version

Question 5

Why should secrets not be placed in source code?

A. Source code cannot contain strings

B. Version history and logs may expose them to unauthorized users

C. Secrets cannot be used by applications

D. Secret values always reduce network bandwidth

Correct Answer: B. Version history and logs may expose them to unauthorized users

Question 6

What does idempotence mean in configuration management?

A. Every operation must fail on its second execution

B. Repeated application converges to the same intended result

C. Only one server may receive configuration

D. Configuration must be written in machine code

Correct Answer: B. Repeated application converges to the same intended result

Question 7

Which is an example of policy as code?

A. A verbal instruction to encrypt databases

B. A machine-evaluated rule rejecting unencrypted storage

C. A manually printed deployment checklist

D. A password written on an administrator’s desk

Correct Answer: B. A machine-evaluated rule rejecting unencrypted storage

Question 8

What is a principal benefit of blue-green deployment?

A. It eliminates the need for monitoring

B. It permits controlled traffic switching and rollback between environments

C. It guarantees that databases never require migration

D. It requires only one running application version

Correct Answer: B. It permits controlled traffic switching and rollback between environments

Question 9

Which action best supports environment consistency?

A. Use unrelated templates in development and production

B. Allow manual production fixes without recording them

C. Reuse versioned modules while making intentional differences explicit

D. Copy secrets directly from production into test systems

Correct Answer: C. Reuse versioned modules while making intentional differences explicit

Question 10

Why is a plan reviewed before applying an IaC change?

A. To identify resource replacements, exposure changes, and possible data loss

B. To ensure that no infrastructure will ever change

C. To bypass access controls

D. To convert all declarative definitions into shell scripts

Correct Answer: A. To identify resource replacements, exposure changes, and possible data loss

DevOps
Chapter 7 of 15