How the Patterns Interact
These three patterns are not independent choices — they work together as a system. Understanding how they compose is what allows you to design IaC architectures that scale to large organizations.
Consider a real-world scenario: a Platform Engineering team supporting 30 product teams at a company running on AWS.
Layer 1 — Resource Modules (Dependency Inversion)
At the bottom, resource modules are thin wrappers around single AWS resources. They accept all their dependencies as inputs and create nothing they don't own — an EC2-instance module, for example, accepts an AMI ID, instance type, subnet ID, and security group IDs, and creates exactly one instance.
Layer 2 — Service Modules (Composition)
Service modules compose resource modules into logical units. A web-service module composes an EC2 instance, a load balancer, and an auto-scaling group. Outputs from one resource module feed as inputs to another.
Layer 3 — Platform Modules (Facade)
Platform modules wrap service modules in a Facade. They expose only the variables product teams need to make decisions — a service name, an image URI, a replica count — while hiding encryption, IAM, logging, monitoring, and tagging standards entirely behind the interface.
The result: A product team's entire infrastructure is three lines — a module call naming the platform module, a service name, an image, and a replica count. The platform team controls everything else. Compliance is structural, not procedural.
Key Point: The three-pattern stack is not theoretical — it is the architecture used by mature platform engineering teams at companies like Stripe, Airbnb, and HashiCorp's own internal teams. The patterns are mutually reinforcing: Dependency Inversion makes modules composable, Composition builds service-level abstractions, and Facade makes those abstractions accessible to non-infrastructure engineers. Adopt them incrementally: start with Dependency Inversion (it has the highest immediate ROI), then introduce Composition as your module library grows, then add Facades when you have a stable service module to wrap.