Resources 8 min read

Terraform and Infrastructure as Code for Drupal

What belongs in Infrastructure as Code for a Drupal estate, how to structure it across many sites, and why state is the part that needs a custody decision before the first apply.

Rolled architectural floor plans on a desk beside a pen, a scale rule and drafting tools.

Infrastructure as Code is usually sold on repeatability, which is true and slightly beside the point for an estate migration. The property that actually matters is that the environment becomes reviewable. A change to production networking arrives as a pull request rather than as a memory of a console session.

HashiCorp describes Terraform as an infrastructure as code tool that lets you build, change, and version cloud and on-prem resources safely and efficiently. This article is about what that means when the workload is Drupal and there are forty of them.

What belongs in code, and what does not

The boundary is worth drawing early, because putting the wrong things in Terraform is a common way to make it unpleasant to use.

In code: networking and segmentation, compute and its scaling rules, the database service and its parameters, object storage and lifecycle rules, cache and search services, load balancers and their health checks, edge configuration, identity roles and policies, secret stores, backup plans and retention, monitoring resources, alarms and log destinations.

Not in code: secret values, the Drupal application itself, site content, and anything whose natural lifecycle is a release rather than an environment.

That last distinction is the one teams get wrong. Terraform describes the environment. The pipeline moves the application into it. When Terraform starts deploying application code, environment changes and releases become entangled and neither can move independently.

State is the part to decide first

HashiCorp is explicit that Terraform must store state about your workspace's managed infrastructure and configuration, that storing it locally makes collaboration difficult, and that mishandling it can result in data loss or exposure of secrets stored in the state file.

Read that last clause carefully. State can contain secrets. It is therefore not a build artifact, it is a sensitive asset, and it needs the same treatment as any other.

Four decisions to make before the first apply, not after.

  • Where it lives. Remote, versioned, encrypted, with access restricted to the identities that need it.
  • Who can read it. Assume anyone who can read state can read a secret that leaked into it.
  • How it is locked. Two concurrent applies against one state is how an environment gets damaged.
  • How it is split. One enormous state for the whole estate makes every change a risk to everything.

The last point deserves its own section.

Structuring it for an estate

A single Drupal site is straightforward. Forty sites is where the design decision appears, and the useful frame is blast radius: what else could this change break?

The arrangement that tends to survive contact with an estate has three layers.

  1. Shared foundation. Networking, shared services, identity foundations, logging destinations, the edge. Changes here are rare, reviewed carefully, and affect everything.
  2. Per environment. The resources that define development, staging and production for a given platform tier.
  3. Per site. What genuinely differs between sites: a database, a bucket, a hostname, a certificate, a scaling profile.

Each layer has its own state. The per site layer is where a reusable module earns its keep: a site becomes a small set of inputs against a shared definition rather than a fresh copy of a hundred lines of configuration. That is also what makes site provisioning something a pipeline can offer as a self-service action, which is the subject of self-service platform operations.

The alternative, copying a directory per site, works for five and becomes unmaintainable somewhere around fifteen, usually at the moment a security change has to be applied everywhere at once.

What Drupal specifically needs from the environment

Drupal is an ordinary PHP application with three characteristics that shape the infrastructure.

  • It has a database and it matters. Sizing, parameter groups, connection limits, backup windows and restore capability are not defaults to accept. The database is where the site actually lives.
  • It writes files. Public and private file directories both need somewhere durable and shared across application instances. Private files need access mediated by the application rather than served directly, which is an access policy decision and not just a bucket.
  • It caches aggressively, in layers. Application cache, an object cache service, and an edge. Each layer needs an invalidation story, and the edge needs to know which responses are safe to cache. Getting that wrong is how an authenticated page ends up in a shared cache.

Search deserves a mention because it is frequently forgotten in the inventory and then discovered during the pilot. If the site uses an external search service, that service is part of the environment and belongs in the definitions.

Applying it safely

Terraform should be run by a pipeline rather than from a laptop, for the same reason application deploys are: so that what happened is recorded and repeatable.

A workable arrangement:

  • A change opens a pull request. The pipeline produces a plan and posts it for review, so the reviewer sees the consequence rather than the diff.
  • Applying to production requires an approval. Microsoft describes control over whether a stage should run as being exercised through approvals and checks, which is what makes that a governed step.
  • The identity that applies to production is not the identity that applies to development.

Two operational warnings from experience. A plan that proposes to destroy and recreate a database is a plan to be read very carefully, and it is worth adding explicit protection to stateful resources so that outcome cannot arrive by accident. And drift is real: somebody will change something in a console during an incident, entirely reasonably, and the definitions will no longer match reality. Detect drift on a schedule rather than discovering it during the next apply.

Getting there from an estate that was built by hand

Most organizations reading this do not have a blank cloud account. They have infrastructure that exists, was created through a console over several years, and is currently working. The question is how to get it under code without an outage.

Importing everything is the obvious approach and usually the wrong one. An import produces definitions that describe what somebody built by hand, including the accidents, and you inherit a configuration nobody designed with none of the review that would have caught it.

The approach that tends to work on a migration is to write the definitions for the target and let the old estate stay as it is until it is retired. You are building a new platform anyway. The existing infrastructure does not need to be brought under code; it needs to be decommissioned, and a decommissioning plan is a much smaller piece of work than a reverse engineering exercise.

Where infrastructure genuinely must stay and come under code, three practical notes:

  • Import in small pieces, starting with the least stateful. Networking before databases. An import that goes wrong on a subnet is recoverable; one that goes wrong on a production database is not.
  • Expect the first plan after an import to propose changes. That is the definitions and reality disagreeing, and reading those differences carefully is the real value of the exercise. Some of them will be settings nobody knew were set.
  • Protect stateful resources explicitly before the first apply. Not after the first alarming plan.

The inventory that tells you which of those situations you are in is the same one that drives everything else, and it is described in the Drupal site complexity assessment.

The proof that it works

There is one test, and it is not a document.

Destroy a non-production environment and rebuild it from the definitions. If it comes back, you have a platform. If it does not, you have a server that happens to be running and a disaster recovery plan that is a hypothesis.

Run that test before the first production site migrates, and run it again periodically, because it decays. It is also the cheapest possible rehearsal for the recovery scenarios in backup and disaster recovery.

What Terraform does not replace

Worth stating because the claim is occasionally made.

Terraform provisions resources. It does not deploy Drupal, does not run database updates or import configuration, does not monitor anything, and does not answer a phone at three in the morning. Positioning it as a replacement for a managed Drupal platform mistakes one row of the list for the list, and the full version of that list is in what actually has to be rebuilt.

Where it sits alongside the other two planes is set out in Azure DevOps for enterprise Drupal: delivery orchestration, infrastructure definition and Drupal lifecycle operations are three jobs and three tools.

Infrastructure as Code is the foundation the rest of the enterprise Drupal modernization capability stands on, which is why it is built and proved before any site moves. If you would like a review of an existing set of definitions, that is a good conversation to have early.

Sources

The external statements on this page are quoted from the following, each re-read on 10 September 2026.

About LABUSA

LAB Information Technology Incorporated (LABUSA) is a trusted provider of managed IT solutions, empowering organizations with secure, efficient, and scalable technologies. With expertise spanning cybersecurity, cloud services, enterprise software, and data management, LABUSA helps clients modernize operations, strengthen compliance, and optimize performance. Our customer-focused approach ensures tailored solutions that align with organizational goals while maintaining the highest standards of reliability and security. Headquartered in Houston, Texas, LABUSA serves government agencies, corporations, and nonprofits across the United States and internationally.