Continuous Integration and Continuous Deployment (CI/CD)

Chapter 6
Infrastructure as Code and Environment Automation

Post Graduate Program in Dev Ops
Continuous Integration and Continuous Deployment (CI/CD)   •   Post Graduate

6. Infrastructure as Code and Environment Automation

Introduction and Context

Continuous integration and continuous deployment depend on more than automated build and release pipelines. A pipeline can compile software, execute tests, and deploy an artifact, yet still produce unreliable outcomes if the environments receiving that artifact are inconsistent. Differences in operating-system packages, network rules, database schemas, runtime versions, permissions, or configuration values frequently create the familiar problem of software working in one environment but failing in another.

Infrastructure as Code (IaC) addresses this problem by representing infrastructure in machine-readable definitions that can be versioned, reviewed, tested, and executed automatically. Environment automation extends the idea to the complete operational context in which an application runs: compute, storage, networks, identity, observability, middleware, databases, policies, and configuration. Together, IaC and configuration management establish a repeatable path from an empty account or data centre to a functioning application platform.

The subject is central to DevOps because it converts infrastructure from an individually assembled product into a reproducible, observable, and governable process. It also introduces new responsibilities. Teams must manage infrastructure state, detect and correct drift, protect secrets, control changes, and decide when to use mutable configuration or immutable replacement. These are technical and managerial decisions, not merely tool-selection exercises.

Learning Objectives

After studying this chapter, students should be able to:

1. Explain the purpose, principles, and lifecycle of Infrastructure as Code.

2. Distinguish declarative provisioning, imperative automation, configuration management, and immutable infrastructure.

3. Describe state management, drift detection, idempotence, dependency handling, and environment parity.

4. Select suitable provisioning and configuration tools for different organizational contexts.

5. Integrate infrastructure changes with CI/CD, testing, policy controls, and approvals.

6. Design approaches for secrets management, security, governance, and disaster recovery.

7. Evaluate the risks, trade-offs, and organizational implications of environment automation.

From Hand-Built Servers to Reproducible Environments

Traditional infrastructure administration often relied on manual procedures: an engineer created a virtual machine, installed packages, edited configuration files, opened firewall ports, and recorded the result in a document. Such environments may function, but their actual configuration is partly undocumented and dependent on personal knowledge. Rebuilding them is slow and uncertain.

Automation improves repeatability, but automation itself has different forms. An imperative script specifies a sequence of actions: create a network, install a package, modify a file, and restart a service. A declarative definition describes the desired end state: a network must exist with specified properties and a service must run with a particular configuration. The automation engine determines the actions required to reach that state.

Declarative automation is especially valuable when the infrastructure is complex. It supports convergence: repeated execution should move the environment toward the same desired state rather than produce duplicated or conflicting resources. This property is closely associated with idempotence, meaning that applying the same operation more than once has the same effective result as applying it once.

IaC generally covers provisioning resources such as virtual networks, subnets, compute instances, containers, databases, load balancers, identity policies, and monitoring components. Configuration management operates inside those resources or on operating systems and services, applying packages, users, files, service settings, and security baselines. In practice, the boundary is not absolute. Tools may perform both functions, and modern platforms often package application, infrastructure, and policy definitions together.

A Conceptual Model of Infrastructure Automation

A useful model separates five layers:

  • Resource layer: networks, compute, storage, databases, and cloud services.
  • Platform layer: operating systems, container runtimes, clusters, middleware, and managed service settings.
  • Application layer: deployment manifests, service configuration, schemas, and release artifacts.
  • Policy layer: identity, compliance rules, cost controls, security constraints, and approved regions or versions.
  • Observation layer: logs, metrics, traces, health checks, audit records, and drift signals.

The layers are related but should not be confused. Provisioning a database does not automatically establish correct application schema migration practices. Creating a Kubernetes cluster does not guarantee secure workload configuration. An effective design defines ownership and interfaces between layers.

A typical lifecycle contains the following activities: authoring definitions, validating syntax and policy, planning changes, reviewing them, applying approved changes, verifying the result, monitoring drift, and retiring obsolete resources. CI/CD provides the control path for this lifecycle. Infrastructure changes should be treated as changes to a production system, not as informal scripts executed from a developer workstation.

Important Concepts and Terminology

Desired state is the configuration an environment is intended to possess. Actual state is the configuration currently present. Automation compares the two and attempts to reconcile differences. State is the recorded information used by an IaC tool to map definitions to real resources. It may include identifiers, dependencies, and selected attributes.

Drift occurs when actual infrastructure differs from the approved desired state, often because of manual changes, provider behaviour, emergency intervention, or incomplete automation. Drift is not always malicious or harmful, but undiscovered drift makes future changes unpredictable.

Idempotence means repeated execution produces no additional unintended change. Convergence is the process through which automation moves a system toward its desired state. Dependency graph represents relationships among resources, such as an application depending on a network and a database depending on a subnet.

Environment parity is the degree to which development, testing, staging, and production resemble one another in relevant technical and operational characteristics. Parity does not require identical scale; it requires that differences are deliberate and understood.

Immutable infrastructure treats deployed infrastructure as replaceable rather than modified in place. A new image or version is built, tested, and substituted for the old one. Mutable infrastructure updates existing machines or resources over time. Configuration management applies and maintains software and operating-system settings, while provisioning creates or allocates infrastructure resources.

Declarative Provisioning and Tool Selection

Terraform and similar tools use declarative resource definitions and maintain state about managed objects. Cloud-specific systems such as AWS CloudFormation, Azure Bicep, and Google Cloud Deployment Manager provide strong integration with their respective platforms. Pulumi permits infrastructure definitions in general-purpose programming languages, which can help teams use familiar abstractions but may also introduce programming complexity.

Configuration-management tools such as Ansible, Puppet, and Chef are designed to install packages, manage files, create users, and control services. Image-building tools such as Packer create reusable machine images. Container and orchestration definitions, including Dockerfiles and Kubernetes manifests, describe another form of environment automation. These categories overlap, but selection should begin with the problem rather than the popularity of a tool.

Tool selection should consider:

  • target platforms and provider support;
  • declarative behaviour and idempotence;
  • state and dependency management;
  • team expertise and maintainability;
  • testing, policy, and review integration;
  • security and secret-handling capabilities;
  • ecosystem maturity and long-term support;
  • portability requirements and risk of provider lock-in.

A general-purpose programming language may be useful when infrastructure requires sophisticated abstraction, but excessive abstraction can hide the resources being changed. Conversely, simple configuration files may become repetitive in large estates. Modules, templates, and reusable components should expose meaningful interfaces while preventing uncontrolled variation.

State, Concurrency, and Drift

State management is one of the most consequential aspects of IaC. Without state, a tool may not know whether a resource already exists, which resource corresponds to a declaration, or which attributes were previously managed. Local state is easy to begin with but creates collaboration, backup, and concurrency problems. Team environments generally require a remote, access-controlled backend with versioning, locking, and recovery procedures.

State may contain sensitive values even when source definitions do not. It therefore requires encryption at rest and in transit, restricted access, audit logging, and careful backup handling. A remote backend solves collaboration problems only if it is itself governed as a critical system.

Concurrent changes create race conditions. Two pipeline executions may plan against the same state and then apply incompatible changes. State locking, serialized applies, change queues, or environment-specific ownership boundaries reduce this risk. A plan should be generated from a known revision of the infrastructure code and reviewed before application.

Drift detection can be scheduled or triggered by events. The organization must then decide whether to import the manual change into code, revert it, or document it as an approved exception. Automatic correction may restore compliance but can also destroy an emergency fix or interrupt a live service. Drift handling therefore requires technical detection and operational judgment.

Configuration Management and Immutable Infrastructure

Configuration management is appropriate when systems must be maintained over time, when legacy servers cannot easily be replaced, or when configuration changes are frequent and small. Its risks include configuration divergence, ordering problems, hidden manual changes, and an accumulation of historical state. A server that has received many incremental modifications may be difficult to understand even if its current state appears correct.

Immutable infrastructure reduces this accumulation. A pipeline builds a versioned image, scans it, tests it, and deploys new instances from it. Replacement strategies such as blue-green or rolling deployment can reduce downtime. Failed releases can be rolled back by selecting a previously known-good image rather than reversing many individual changes.

Immutability does not mean that nothing changes. Data, external configuration, certificates, and runtime scaling still change. The principle is that the base runtime should be reproducible and replaced through a controlled process. It may be impractical for stateful systems unless storage, replication, backup, and migration procedures are designed separately.

A hybrid model is common: immutable images for operating-system and application layers, declarative provisioning for cloud resources, and limited configuration management for runtime or legacy requirements. The correct choice depends on recovery objectives, workload statefulness, platform capabilities, and operational maturity.

Environment Parity and Promotion

Separate environments serve different purposes, but uncontrolled differences reduce the value of testing. Development may use smaller resources, while staging may approximate production architecture and security boundaries. Differences should be parameterized rather than encoded as unrelated copies of infrastructure definitions.

A strong promotion model uses the same application artifact across environments and changes only approved environment-specific inputs. Infrastructure code should also be shared through modules or common components, with explicit variables for scale, capacity, credentials references, and endpoint values. If staging uses a different database engine, identity model, or networking pattern from production, tests may provide false confidence.

Parity includes operational properties, not only hardware. Logging, monitoring, backup, access control, deployment mechanisms, and failure recovery should be exercised before production. Ephemeral environments created for pull requests or integration tests can improve feedback, provided their cost, data protection, and cleanup are controlled.

Secrets, Security, and Governance

Secrets include passwords, private keys, tokens, certificates, and connection strings. They should not be committed to source control, embedded in images, or exposed in pipeline logs. IaC should refer to secrets by controlled identifiers and retrieve values at deployment or runtime from a secrets manager. Rotation, expiry, least privilege, and auditability are essential.

Security must be implemented as code where practical. Network rules, encryption requirements, identity policies, approved images, and mandatory tags can be checked before deployment. Policy-as-code tools can reject non-compliant plans, such as public storage, unrestricted administrative access, or resources without ownership metadata.

Governance should distinguish separation of duties from unnecessary bureaucracy. Developers may propose changes, automated checks may evaluate them, and authorized pipelines may apply them. Emergency access should be time-limited, logged, reviewed, and reconciled with source-controlled definitions. Compliance evidence is stronger when generated from version history, pipeline records, policy results, and deployment logs rather than assembled manually after the fact.

Integrating IaC with CI/CD

An infrastructure pipeline commonly performs formatting and static validation, dependency and security scanning, unit tests for modules, policy checks, a plan or preview, peer approval, controlled application, and post-apply verification. Production changes may require an additional approval or a change window, depending on risk and organizational policy.

Testing infrastructure is not limited to syntax. Unit tests can validate module logic; integration tests can create temporary resources and verify connectivity, permissions, and service behaviour; compliance tests can inspect the resulting environment; and destructive tests can evaluate recovery and deletion safeguards. Tests should be proportionate to risk and should avoid leaving resources or sensitive data behind.

Application and infrastructure pipelines should be coordinated but need not be identical. A database schema change, for example, may require backward-compatible sequencing: expand the schema, deploy code that supports both versions, migrate data, and later remove obsolete structures. Destroy operations deserve special protection, including explicit approval, backups, and environment restrictions.

Illustrative Case Study: Standardising a Multi-Environment Payment Platform

Background

A fictional financial-services company, Northstar Payments, operates a payment API in development, staging, and production. Development was created by engineers manually, staging used a mixture of scripts, and production was managed by a cloud operations team. The environments differed in database versions, network rules, logging, and identity permissions.

Situation and Problem

A release passed application tests in staging but failed in production because a required database extension was absent and a network policy blocked a service-to-service connection. The organization also discovered that an emergency production change had never been recorded. Recovery from a failed deployment was slow because servers had been modified in place.

Analysis

The immediate failure was technical, but the deeper causes were configuration drift, weak environment parity, unclear ownership, and the absence of a controlled infrastructure delivery process. Manual documentation could describe an intended environment but could not reliably represent actual state. The company also stored several deployment credentials in pipeline variables with broad permissions.

Approach and Solution

Northstar defined reusable infrastructure modules for networks, managed databases, identities, monitoring, and application services. Environment-specific values were placed in reviewed configuration files, while passwords and certificates were referenced from a managed secrets service. A remote state backend with locking and access controls was introduced.

The team built immutable application images and used a rolling deployment strategy. Database changes followed an expand-and-contract migration method. Pull requests triggered formatting, validation, security scanning, policy checks, and a plan. Staging applied the reviewed plan automatically after tests; production required an additional approval. A scheduled drift report identified manual changes, which were either codified or reverted.

Outcome

The environments became structurally consistent, and the same tested application artifact was promoted through the delivery path. Rollback involved selecting a previous image, while infrastructure changes were traceable to reviewed commits. The company did not eliminate all incidents, but it reduced uncertainty and improved the speed of diagnosis and recovery.

Learning Points

The case demonstrates that IaC is not simply a replacement for shell scripts. Its value arises from version control, review, state discipline, security controls, testing, and organizational ownership. It also shows that environment parity must include identity, observability, and operational procedures, not only compute resources.

Challenges, Limitations, and Common Mistakes

IaC can reproduce a poor design very efficiently. Incorrect dependency modelling, overly broad permissions, insecure defaults, or excessive resource size may be propagated across every environment. Automation also creates blast radius: a faulty module or destructive change can affect many systems.

Common mistakes include storing secrets in repositories or state without protection, allowing direct console changes, using one enormous configuration file, copying environments instead of composing reusable modules, ignoring deletion and backup behaviour, and treating a successful plan as proof that the application will work. Other failures arise from inadequate ownership, unreviewed provider upgrades, lack of state recovery testing, and insufficient cleanup of temporary environments.

Abstraction has limits. Provider APIs may differ, managed services may expose unique capabilities, and a supposedly portable definition may still depend on platform-specific networking or identity models. Teams should prefer explicit, well-tested portability boundaries over claiming universal portability.

Professional and Managerial Implications

Environment automation changes the distribution of responsibility. Developers need enough infrastructure literacy to understand deployment constraints; platform teams provide safe reusable capabilities; security teams encode controls; and managers must fund maintenance, testing, and skills rather than treating automation as a one-time project.

Useful measures include deployment lead time, change failure rate, time to restore service, drift findings, percentage of infrastructure under code, policy-violation rates, recovery-test success, and the age of unmanaged resources. Metrics should encourage reliability rather than reward the volume of automation. A high percentage of coded resources is not valuable if the code is unreviewed or impossible to recover.

Current Developments and Emerging Practice

Platform engineering increasingly provides internal developer platforms that expose approved infrastructure through self-service interfaces and reusable templates. GitOps extends the declarative model by treating a version-controlled repository as the authoritative source and using controllers to reconcile runtime environments. Software supply-chain security now includes image provenance, dependency attestations, signed artifacts, and verification of deployment inputs.

Policy engines are becoming more expressive, enabling organizations to evaluate cost, security, data residency, and operational requirements before provisioning. Generative AI may assist with configuration explanation, code suggestions, documentation, and anomaly investigation, but generated infrastructure still requires expert review, testing, least-privilege controls, and protection against fabricated or unsafe recommendations. Human accountability remains necessary for high-impact changes.

Best Practices

1. Keep infrastructure definitions, modules, policies, and documentation under version control.

2. Use remote, encrypted, access-controlled state with locking, versioning, and tested recovery.

3. Treat plans as reviewable change proposals and applications as controlled operations.

4. Prefer immutable runtime artifacts where replacement is practical; isolate unavoidable mutable state.

5. Parameterize deliberate environment differences and promote the same tested artifacts.

6. Store secrets in dedicated systems and grant narrowly scoped, auditable access.

7. Test modules, policies, integrations, recovery procedures, and destructive operations.

8. Detect drift continuously and define an explicit response process.

9. Limit blast radius through modules, accounts, workspaces, approvals, and progressive rollout.

10. Measure operational outcomes, not merely the number of scripts or resources automated.

Chapter Summary

Infrastructure as Code represents infrastructure in versioned, machine-readable form so that environments can be created, reviewed, tested, and reproduced. Declarative provisioning expresses desired state, while configuration management maintains systems and immutable infrastructure replaces rather than continually modifies runtime images. State enables resource tracking but must be secured, locked, backed up, and monitored for drift. Environment parity requires consistency in architecture, identity, security, observability, and operational behaviour, with deliberate differences represented as parameters. Effective IaC integrates with CI/CD through validation, policy checks, planning, approval, controlled application, and verification. Secrets management, governance, recovery, and ownership are essential to its professional use. Tool selection should follow organizational needs, platform constraints, risk, and maintainability rather than fashion.

Key Terms

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

Declarative configuration: A description of the desired end state rather than an action sequence.

Imperative automation: Automation that specifies the ordered actions to perform.

Desired state: The approved configuration an environment should possess.

Actual state: The configuration currently present in an environment.

State: Stored information that maps IaC definitions to real resources and dependencies.

Drift: Difference between approved desired state and actual infrastructure.

Idempotence: Property in which repeated execution produces no unintended additional change.

Convergence: Movement of a system toward its desired state through reconciliation.

Configuration management: Automated control of operating-system and service settings.

Provisioning: Creation or allocation of infrastructure resources.

Immutable infrastructure: Infrastructure replaced from versioned artifacts instead of modified in place.

Environment parity: Deliberate similarity among development, test, staging, and production environments.

Policy as code: Machine-enforceable rules governing infrastructure and operational decisions.

Remote state: Centrally managed state storage supporting collaboration and controlled access.

State locking: A mechanism preventing conflicting simultaneous state modifications.

Secrets management: Secure storage, retrieval, rotation, and auditing of sensitive values.

GitOps: A model in which version-controlled declarations guide automated reconciliation of environments.

Infrastructure module: A reusable, parameterized group of infrastructure definitions.

Blast radius: The extent of systems affected by an erroneous or harmful change.

Review Questions

Short Answer Questions

1. What distinguishes declarative provisioning from imperative automation?

2. Why is state required by many IaC tools?

3. Define infrastructure drift and identify two possible causes.

4. What is meant by environment parity?

5. Why should secrets not normally be embedded directly in IaC files?

Long Answer Questions

1. Explain the lifecycle of an infrastructure change from authoring through post-apply verification.

2. Compare mutable and immutable infrastructure, including appropriate use cases and limitations.

3. Discuss the relationship among provisioning, configuration management, and application deployment.

4. Explain how remote state, locking, backups, and access control support reliable collaboration.

5. Design a CI/CD workflow for infrastructure that includes testing, policy, approval, deployment, and drift management.

Analytical / Application Questions

1. A staging environment passes tests, but production differs in database version, identity permissions, and network policy. Analyse the likely causes and propose a parity strategy.

2. Two engineers apply conflicting infrastructure changes at the same time, and a manual emergency change is later discovered. Recommend a state, locking, drift, and governance response.

3. An organization must choose between Terraform, a cloud-native provisioning tool, and Ansible for a new platform. Develop decision criteria and justify a possible hybrid architecture.

22. Multiple Choice Questions with Answers

Question 1

Which situation best demonstrates infrastructure drift?

A. A planned module creates a new subnet

B. A production firewall rule is changed manually and is absent from the approved definitions

C. A pipeline validates an infrastructure file

D. A new application image is promoted to staging

Correct Answer: B. A production firewall rule is changed manually and is absent from the approved definitions

Question 2

What is the principal advantage of declarative infrastructure definitions?

A. They require every operational action to be written in sequence

B. They eliminate the need for testing

C. They describe the desired state and allow tooling to determine required changes

D. They guarantee that all cloud providers expose identical features

Correct Answer: C. They describe the desired state and allow tooling to determine required changes

Question 3

Why should a collaborative IaC system use remote state locking?

A. To prevent two changes from modifying shared state inconsistently

B. To encrypt application source code

C. To increase the size of virtual machines

D. To replace all approval procedures

Correct Answer: A. To prevent two changes from modifying shared state inconsistently

Question 4

Which practice most strongly supports immutable infrastructure?

A. Editing production servers directly after every release

B. Building a versioned image, testing it, and replacing existing instances

C. Keeping undocumented changes on long-lived servers

D. Installing packages manually during an incident

Correct Answer: B. Building a versioned image, testing it, and replacing existing instances

Question 5

A team wants to prevent public storage resources from being created. Which control is most appropriate?

A. A policy-as-code check applied before deployment

B. A larger application server

C. A local developer note

D. A database schema migration

Correct Answer: A. A policy-as-code check applied before deployment

Question 6

Which approach best protects credentials used by an infrastructure pipeline?

A. Commit them to a private source repository

B. Place them in an image so every server can read them

C. Reference a managed secrets service with narrowly scoped access

D. Print them in deployment logs for auditing

Correct Answer: C. Reference a managed secrets service with narrowly scoped access

Question 7

Why is using the same application artifact across environments valuable?

A. It guarantees identical capacity in every environment

B. It reduces the chance that testing and production run different software

C. It removes the need for environment-specific configuration

D. It prevents all infrastructure changes

Correct Answer: B. It reduces the chance that testing and production run different software

Question 8

A configuration-management tool repeatedly installs a package without recognizing that it is already present. Which property is missing?

A. Idempotence

B. Portability

C. Encryption

D. Observability

Correct Answer: A. Idempotence

Question 9

Which response is most appropriate when scheduled drift detection finds an undocumented production change?

A. Ignore it permanently because the service is currently healthy

B. Automatically delete the entire production environment

C. Determine whether to codify, revert, or formally approve the change

D. Remove state locking from the platform

Correct Answer: C. Determine whether to codify, revert, or formally approve the change

Question 10

Why might an organization combine immutable images, declarative provisioning, and configuration management?

A. The approaches address different layers and operational constraints

B. Combining them guarantees zero deployment failures

C. They are all identical techniques with different names

D. Configuration management makes state and policy unnecessary

Correct Answer: A. The approaches address different layers and operational constraints

Continuous Integration and Continuous Deployment (CI/CD)
Chapter 6 of 14