Infrastructure as Code is the practice of defining and provisioning infrastructure through machine-readable definition files that get versioned, reviewed, and applied through the same tooling that handles application code. The definitions describe what should exist (a Kubernetes cluster, a database, a load balancer, the networking that connects them) and a tool applies the definitions against a cloud or other provider. Real examples reveal which IaC tools have actually displaced manual provisioning at scale, how teams structure their IaC repositories, and where the discipline still struggles despite years of maturity.
The pattern emerged from the recognition that manual cloud console clicking did not scale beyond toy environments. Production systems with hundreds of resources across multiple environments and accounts could not be reliably provisioned by hand. The same engineering practices that worked for application code (version control, code review, testing, CI/CD) needed to work for infrastructure. IaC tools made that possible.
The category in 2026 is dominated by a handful of tools. Terraform (now in its OpenTofu fork after HashiCorp's license change) holds the largest market share with the broadest provider support. AWS CDK uses general-purpose programming languages to generate CloudFormation. Pulumi takes a similar programming-language approach across multiple clouds. Each has its niche; Terraform remains the safe default for cross-vendor work.
What separates IaC done well from IaC done poorly is usually the discipline around state, modularity, and change management. IaC done well has clean module structures, isolated state files, explicit environments, and CI-driven deployment with policy enforcement. IaC done poorly has monolithic state files, copy-pasted modules, environment drift, and changes that get applied manually outside the pipeline.
This page surveys real IaC implementations at companies of different sizes, the patterns that have emerged for managing IaC at scale, and the trade-offs between the major tools. The tooling continues to evolve; the patterns about repository structure, state management, and operational practices are more enduring.
HashiCorp itself, the creator of Terraform, runs extensive Terraform across their own infrastructure. The dogfooding informs the product's direction. The license change to BSL in 2023 caused community fragmentation; the OpenTofu fork (now governed by the Linux Foundation) preserved the open-source version, and many organizations migrated to OpenTofu for their new work.
Twilio runs IaC across their infrastructure for the communications platform. The published material describes their Terraform usage, module patterns, and the operational practices around team-owned infrastructure. The patterns are recognizable as standard mature IaC practice.
Adobe has discussed their Terraform usage at scale across their cloud infrastructure. The patterns include strong module conventions, state isolation per service, and CI-driven deployment. The maturity of practice is typical of large enterprises that have invested in IaC for years.
Slack, GitHub, Stripe, and many other technology companies run extensive Terraform or alternative IaC across their infrastructure. The conference talks and blog posts from these companies describe similar patterns: modular Terraform, isolated state, automated deployment with manual approval gates for production, drift detection, and policy enforcement.
AWS uses CloudFormation and CDK heavily for their own internal infrastructure (this is implied by the products' development trajectory; AWS does not publish detailed internal architecture). CDK has grown significantly since its 2019 release because it lets engineers use TypeScript, Python, or other languages instead of HCL or YAML.
Enterprise adopters span banks (Goldman Sachs, Capital One), retailers (Target, Walmart), telecoms (Vodafone, Verizon), and government agencies. The patterns at enterprise scale add additional layers (cross-account governance, FinOps integration, compliance enforcement) but the core IaC practices are recognizable.
Terraform remains the default. HashiCorp Configuration Language (HCL) is purpose-built for describing infrastructure; the provider ecosystem covers thousands of services across cloud, SaaS, and on-premise systems. The mature documentation, large community, and broad job market for Terraform skills make it the safe choice for most teams.
OpenTofu is the open-source Terraform fork that emerged after HashiCorp's BSL license change. The fork has gained adoption, particularly at organizations that needed pure open-source licensing. The two tools remain compatible for now; whether they diverge significantly in the future depends on community direction.
AWS CDK lets engineers define infrastructure in TypeScript, Python, Java, C\#, or Go, with the tool synthesizing CloudFormation templates. The programming-language approach gives access to abstractions and library ecosystems that HCL cannot match. The trade-off is AWS-specific scope; CDK only generates CloudFormation, not multi-cloud infrastructure.
Pulumi takes a similar programming-language approach across multiple clouds. The tool fits teams that want CDK-style abstractions across vendors. Adoption is smaller than Terraform but real; the community is active. The pricing for the commercial backend has driven some teams to self-managed state.
Crossplane runs IaC inside Kubernetes through Custom Resource Definitions. The pattern fits teams that have standardized on Kubernetes and want infrastructure to feel like the rest of their Kubernetes resources. Adoption is growing in cloud-native organizations.
Ansible, Chef, and Puppet are configuration management tools that overlap with IaC for some use cases. They are stronger for VM configuration (installing packages, managing files, running services) than for cloud resource provisioning. Many production stacks combine Terraform for provisioning with Ansible for configuration.
Monorepo with per-service modules. All infrastructure lives in one repository organized by service. Each service has a directory with its modules and state references. The pattern fits smaller organizations where one repository is manageable.
Polyrepo with separate infrastructure per service. Each service's infrastructure lives in the service's own repository alongside the application code. The pattern fits teams that own their full stack and want infrastructure changes to flow through the same review process as code changes.
Shared modules repository plus service-specific repositories. Common modules (a standard Kubernetes deployment, a standard database setup) live in a shared repository. Services import the modules and instantiate them with service-specific parameters. The pattern enables consistency without forcing all services into one repository.
Environment-per-directory inside a service repository. Production, staging, and development environments each have their own Terraform directory with their own state. Changes promote across environments through controlled promotion. The pattern is the most common organization for environment management.
Workspace-based environments using Terraform's workspace feature. The same configuration applies across environments through workspace selection. The pattern reduces code duplication but mixes environments in ways that can produce mistakes; the explicit-directory approach is more common in production.
The choice depends on team structure and infrastructure complexity. Small teams benefit from monorepo simplicity; large teams need polyrepo isolation; most settle somewhere in between with shared modules plus per-service repositories.
Terraform state in S3 with DynamoDB locking is the most common backend. The pattern is simple, reliable, and well-supported. The state file is the source of truth for what infrastructure exists; locking prevents concurrent writes that would corrupt it.
Terraform Cloud, OpenTofu's planned managed service, Spacelift, Env0, Scalr, and similar platforms provide managed state plus additional features for collaboration, policy enforcement, audit, and CI integration. The platforms reduce operational burden but add cost and vendor dependency.
State isolation by environment and component prevents blast radius from concentrating in one state file. A change to one service's infrastructure should not require touching another service's state. The pattern requires explicit decisions about state granularity and the inter-state references that span them.
State migration tools handle the inevitable need to restructure state as the codebase evolves. Terraform's state mv command for renaming. State import for adopting existing resources. Manual state surgery for complex cases. The tools work but the operations require care; mistakes corrupt state and require restoration from backup.
The state is the most operationally sensitive artifact in an IaC setup. Backups, access control, audit logging, and disaster recovery for state files all matter. Treating state as throwaway leads to recovery scenarios that are painful when they happen.
CI-driven plan and apply. Every pull request triggers a terraform plan that posts to the PR. Reviewers see exactly what would change. Merging triggers terraform apply. The pattern brings standard code review discipline to infrastructure changes.
Policy enforcement through OPA, Sentinel, or custom tooling. Policies catch dangerous changes at the plan stage: unencrypted storage, open security groups, untagged resources, oversized instances. The pattern prevents bad infrastructure from being applied rather than detecting it after the fact.
Drift detection runs periodically to find infrastructure changed outside the IaC. Manual console changes, automatic cloud-provider adjustments, untracked modifications. The drift gets reported and the team reconciles. Tools include Terraform's built-in plan, third-party services (driftctl, Spacelift), and cloud-native services (AWS Config).
Module versioning lets teams update modules safely. New module versions get released; consumers update at their own pace; breaking changes get major version bumps with migration paths. The pattern matches semantic versioning practices from software libraries.
Cost estimation in CI through Infracost or similar tools surfaces the cost impact of proposed changes. The pattern makes cost visible during review rather than discovering it on the next bill. The discipline helps catch obviously expensive changes before they ship.
Manual console changes that drift from IaC. The change works but the IaC no longer reflects reality; the next apply produces unexpected behavior or fails. The fix is policy that requires IaC-only changes plus drift detection that catches exceptions quickly.
Monolithic state files where one mistake affects everything. The state grows to hundreds of resources; any apply locks the entire state; any error has wide blast radius. The fix is state decomposition into smaller, focused state files per service or environment.
Copy-pasted modules that drift from each other. Three services have similar infrastructure with similar but slightly different module code; updates require touching all of them. The fix is shared modules with versioning.
State corruption from concurrent applies or manual editing. The state file ends up in an inconsistent state; subsequent operations fail mysteriously. The fix is proper locking and treating state surgery as a careful operation rather than a routine fix.
IaC repositories that the team is afraid to touch. The infrastructure code is opaque; nobody fully understands it; changes are postponed. The fix is gradual refactoring, documentation, and periodic clean-up rather than letting the situation continue to degrade.
OpenTofu for new projects if pure open-source licensing matters. Terraform if you are committed to HashiCorp's broader ecosystem or use features specific to Terraform Cloud. The two are currently compatible; the divergence remains modest. Either is a defensible choice.
When you want the abstractions and library ecosystems of a general-purpose programming language. CDK if you are AWS-only and TypeScript or Python is your team's strength. Pulumi if you need similar capabilities across multiple clouds. Terraform remains the safe default; CDK and Pulumi are good alternatives for specific situations.
Match it to your team structure. Single team, monorepo with per-service modules. Multiple teams owning their services, polyrepo with infrastructure in each service repo. Either way, shared modules in a common repository help maintain consistency across services.
S3 with DynamoDB locking is the standard answer for self-managed state. Terraform Cloud, Spacelift, Env0, or similar managed services for teams that want to outsource state management. Never store state in version control; the file contains sensitive information and the workflow does not work well with the version control model.
Reference them from a secrets manager (AWS Secrets Manager, GCP Secret Manager, Vault). The IaC contains references to secrets, not the secrets themselves. The applied infrastructure reads the secrets at runtime through IAM-based access. Never put actual secret values in IaC code or state files where they end up in shared storage.
Small enough to be reusable; large enough to provide meaningful abstraction. A module for a single resource (one S3 bucket) is usually too small. A module for an entire application stack is usually too large. Common sensible granularities include a Kubernetes service with its database and networking, or a complete Cloudfront distribution with its origins.
Through terraform import for existing resources. The pattern is tedious but workable. Tools like terraformer can speed up bulk imports. The work is significant for large existing estates; many enterprises do it gradually over years rather than all at once.
With separate state files per environment and explicit promotion through code review. The same code applies to multiple environments with environment-specific variables. Either directory-per-environment or workspace-based organization works; directory-per-environment is more explicit and less prone to mistakes.
Toward better abstractions for higher-level concepts (whole application stacks, multi-region deployments). Toward more AI assistance in writing and reviewing IaC. Toward tighter integration with policy and cost tooling. Toward continued tool consolidation around a few dominant choices. The discipline is mature; the experience of working in it continues to improve.