Exploring and comparing popular Infrastructure as Code (IaC) tools by implementing the same reference cloud infrastructure using each of them.
Building the same cloud stack with several IaC tools is the fastest way to understand:
- authoring experience & language choices
- state management
- ecosystem maturity (providers, modules, multi-environments)
- testing and CI/CD
- operational concerns like speed, cost, reviewability
iac-comparator gathers these learnings in one codebase.
This section provides a visual representation of the AWS infrastructure, chosen as reference for this project, outlining and describing key components. It allows to understand the high-level architecture and how different services interact with each other.
Here’s a short description of the services presented in the infrastructure diagram:
- Network Layer:
- VPC: it provides private address space, route tables and security boundaries
- Public Subnets (A, B, C):
- Live in separate AZs
- Contain NAT Gateways and any resource that must have a public IP (e.g., load balancers)
- Default route (0.0.0.0/0) goes straight to the Internet Gateway
- Private Subnets (A, B, C):
- Also one per AZ
- Dedicated for backend services like the AWS EKS Cluster (Elastic Kubernetes Service)
- No direct Internet route; 0.0.0.0/0 is sent to the NAT Gateway in the same AZ
- NAT Gateway (one per AZ):
- Lets private resources initiate outbound Internet connections while remaining unreachable from the Internet
- Internet Gateway (single, one per VPC):
- Highly available entry/exit point for anything with a public IP (including each NAT)
- Compute & Orchestration Layer:
- EKS (Elastic Kubernetes Service): EKS manages the containerized application workloads and other platform-related services for example Grafana for dashboarding, Prometheus for metrics, Loki for logging, and ArgoCD as GitOps tool.
- Control plane runs in AWS-managed VPCs; the API endpoint is public but IP-restricted for easy dev use
- Worker nodes sit in the private subnets
- EKS (Elastic Kubernetes Service): EKS manages the containerized application workloads and other platform-related services for example Grafana for dashboarding, Prometheus for metrics, Loki for logging, and ArgoCD as GitOps tool.
- Security & Management Services:
- IAM Roles for giving specific permissions within AWS to role assumers.
- KMS (Key Management Service) which allows to encrypt/decrypt sensitive data, e.g. K8s Secrets.
*You can set the number of Availability Zones to use, as well as the NAT availability strategy setting the corresponding input variable (e.g., azCount and natStrategy in Pulumi TypeScript).
Trade off NAT High Availability Strategy vs Cost
- NAT is AZ-scoped, so it does not automatically fail over to another AZ.
- What Happens to NAT & Internet Access If an AZ Goes Down?
- The NAT in that AZ will go down and internet access will be lost.
- Other AZs keep working because they still have their own NAT Gateways.
- How having one NAT per AZ and spreading node groups across multiple AZs matters
- If AZ-B disappears entirely (power, network or flooding), every node in AZ-B dies and so do its NAT GW and subnets.
- The Kubernetes control plane in AWS immediately sees those nodes as NotReady.
- The scheduler reschedules their pods onto healthy nodes in AZ-A and AZ-C.
- Those pods now use the NATs in AZ-A and AZ-C, so they keep their outbound Internet access.
- About cost:
- By default, each NAT Gateway costs ~$32/month (plus ~$0.045 per GB of traffic).
- 1 NAT Gateway (shared across AZs) > low cost, but introduces a single point of failure.
- 3 NAT Gateways (one per AZ) > resilient setup, but costs ~$100/month baseline, plus per-GB fees in each AZ.
- When to Choose What?
- For production or anything uptime-sensitive > Use one NAT per AZ.
- For dev/test environments with low traffic and tolerance for interruptions > use a single NAT Gateway to save money
- You can also use 2 NAT as a middle path.
- By default, each NAT Gateway costs ~$32/month (plus ~$0.045 per GB of traffic).
This repository is structured by IaC tool. Each tool has its own subdirectory (e.g., terraform/, pulumi/typescript/ and so on).
Every subdirectory includes its own README.md with step-by-step instructions on how to provision the reference architecture with that tool.
⚠️ Note: As this project is still in active development, not all subdirectories are complete yet. Instructions may evolve as implementations progress.
To get started:
-
Clone the repo:
git clone https://github.com/nicolaDeCristofaro/iac-comparator.git cd iac-comparator -
Choose one of the available tools and follow its README.md.
-
Compare the differences in authoring style, workflow, and ecosystem across tools.
This section tracks the progress of implementing the reference architecture across IaC tools. The goal is to eventually have a full side-by-side set of implementations.
| Tool | Language | Status | Notes |
|---|---|---|---|
| Terraform (community modules) | HCL | ⏳ In Progress | |
| Terraform (custom modules) | HCL | ⏳ In Progress | |
| OpenTofu | HCL | 📅 TBD | |
| Pulumi | TypeScript | ⏳ In Progress | |
| Pulumi | Go | 📅 TBD | |
| CloudFormation | YAML | 📅 TBD | |
| AWS CDK | TypeScript | 📅 TBD |
A central objective of this project is to compare tools not just by syntax, but across deeper dimensions like: Authoring experience
- State management
- CI/CD integrations
- Ecosystem maturity
- Testing framework
- Operational concerns (speed, cost, reviewability)
- Policy as Code
- Multi-cloud support
- Secrets management
- Community adoption & popularity
Work is ongoing to document these aspects in dedicated subchapters.
🚧 This comparison is still under construction. Expect refinements and new metrics as the project evolves.
Please refer to the Contributing guide and the Code of Conduct for more information on how to contribute.
This project is licensed under the MIT License.
See LICENSE for details.
- HashiCorp, Pulumi, and AWS for excellent open-source IaC tools
- Inspired by real-world infrastructure needs and personal curiosity 🚀
