Declarative and imperative configuration are two contrasting philosophies for automating the management of systems. In the imperative style, you write out the explicit sequence of actions a tool should perform: create this server, then install that package, then edit this line, then restart the service. The author is responsible for the steps and their order. In the declarative style, you instead describe the desired end state - “there should be three running replicas of this service, configured this way” - and a tool figures out what actions are required to make reality match that description.
Kubernetes is a canonical example of the declarative model. Its documentation explains that “by creating an object, you’re effectively telling the Kubernetes system what you want your cluster’s workload to look like; this is your cluster’s desired state.” Each object carries a spec (the desired state you declare) and a status (the current state the system observes). The control plane runs a continuous reconciliation loop: when it detects a difference between spec and status - for instance, if one of three desired replicas fails - “the Kubernetes system responds to the difference between spec and status by making a correction.” The user never wrote the steps to recreate the replica; they only declared that three should exist.
The declarative model depends on two related properties. The first is convergence: the system repeatedly compares desired state to actual state and takes whatever actions narrow the gap, eventually arriving at the declared end state regardless of where it started. The second is idempotency: applying the same declaration again when the system is already in the desired state should change nothing. Together these make declarative automation safe to run over and over - the same property that lets it detect and correct infrastructure drift.
The imperative model has its own virtues. It is often more direct and easier to reason about for one-off or interactive tasks, and many tools expose imperative commands for quick changes. The Kubernetes documentation, for instance, distinguishes managing objects with imperative commands from managing them declaratively through configuration files. The tradeoff is that imperative scripts must anticipate the current state - they break or behave unpredictably if the system is not in the condition the script assumed - whereas declarative definitions describe an outcome that holds no matter the starting point.
This distinction runs through most of modern infrastructure tooling. Configuration-management systems and infrastructure-as-code tools generally favor declarative definitions precisely because they want repeatable, drift-correcting behavior across fleets of machines. The shift from imperative shell scripts toward declarative, convergent, idempotent definitions is one of the defining changes that made large-scale, automated operations reliable enough to run without a human executing each step.