Infrastructure as Code (IaC) means describing your cloud resources — servers, databases, storage buckets, networking — in a text file, and using a tool to build and manage them from that file. Instead of clicking through a cloud dashboard to set things up, you write a declaration of what you want, and the tool makes it happen. If Cartara flagged this in your diff, you likely have a Terraform, OpenTofu, or similar configuration file that provisions real cloud infrastructure.
Why Clicking Through the Dashboard Fails Over Time
The "click around the cloud console" approach works fine at first and then becomes a serious liability:
It's not reproducible. Six months after you set up production, nobody remembers which settings you toggled. Recreating it in a staging environment becomes archaeology — guessing until it works.
It drifts. Someone makes a "quick fix" in the console that never gets documented. Now your live setup doesn't match anyone's mental model. These undocumented changes are called configuration drift.
It doesn't scale. Setting up one server by hand is fine. Setting up five identical ones, or rebuilding after a failure, is error-prone misery.
IaC fixes this by making the file the source of truth. Want to know exactly how production is configured? Read the file. Want an identical staging environment? Run the same file with different variables.
Declarative vs. Imperative
Most modern IaC tools are declarative: you describe the desired end state ("I want a database, two web servers, and a load balancer with these settings") and the tool figures out how to get there. If a resource already exists, it's left alone. If something's missing, it's created.
This contrasts with imperative approaches — shell scripts that run commands step by step. Declarative is more robust because you can run it repeatedly and always arrive at the same result. This property is called idempotency.
The Main Tools
| Tool | Notes |
|---|---|
| Terraform | The long-time industry standard. Works across all cloud providers. Now owned by IBM and under a more restrictive license since 2023. |
| OpenTofu | The open-source fork of Terraform, created after the license change. Near drop-in replacement — most Terraform configs work unchanged. A CNCF project. |
| Pulumi | IaC using real programming languages (TypeScript, Python, Go) instead of a custom config language. Good if your team prefers code over config syntax. |
| AWS CloudFormation / CDK | AWS-native IaC. CloudFormation uses YAML/JSON; CDK lets you write in TypeScript or Python and compiles to CloudFormation. Locked to AWS. |
For most teams starting today, the Terraform/OpenTofu ecosystem is the default choice because of its breadth of cloud provider support and community resources.
What You'll See in Your Code
A Terraform file declaring an S3 storage bucket with versioning enabled:
resource "aws_s3_bucket" "uploads" {
bucket = "myapp-user-uploads"
}
resource "aws_s3_bucket_versioning" "uploads" {
bucket = aws_s3_bucket.uploads.id
versioning_configuration {
status = "Enabled"
}
}You don't write the API calls to create the bucket — you declare that it should exist, and the tool reconciles reality to match.
Running it looks like:
terraform init # Download providers
terraform plan # Preview what will change
terraform apply # Make the changesThe plan step is one of IaC's biggest advantages: you can see exactly what will be created, modified, or destroyed before anything happens.
State: The Concept That Trips People Up
IaC tools keep a state file — a record of what they've actually created, mapping your config to the real cloud resources. This is how the tool knows whether to create a new resource or leave an existing one alone.
Two things you must get right:
Store state remotely, not on someone's laptop. If the state file lives locally, only that person can run Terraform, and if their machine dies, you lose track of what's deployed. Store it in a remote backend — an S3 bucket, Terraform Cloud, or similar — so the whole team (and your CI pipeline) works from the same state.
Protect it. State files can contain sensitive values like database passwords. Encrypt them and control who can access them.
Immutable Infrastructure
IaC enables a powerful pattern: instead of SSH-ing into a running server to apply patches and updates (which causes drift), you build a brand-new server from your code and replace the old one. Servers become disposable and identical — rebuilt from a known-good definition rather than accumulating undocumented changes over time.
Containers take this idea to its logical conclusion: your application is packaged with everything it needs, and deploying means replacing the container, not modifying it.
How It Fits With Everything Else
IaC is what makes GitOps possible — if your infrastructure is declared in Git files, an automated tool can continuously reconcile your live environment to match. It plugs into your CI/CD pipeline so infrastructure changes get reviewed and applied automatically. It's also the foundation for having truly identical staging and production environments.
Do You Need This Yet?
Honestly, maybe not on day one. If you're using managed platforms like Vercel, Railway, or Supabase, a lot of infrastructure is handled for you and IaC would be overkill. Consider reaching for it when: you're managing real cloud resources directly (EC2 instances, VPCs, RDS), you need identical staging and production environments, more than one person touches infrastructure, or you've lost track of how something was set up.