The term "Infrastructure as Code" (IaC) was coined in 2006. It stuck. But it's wrong.
Here's what Terraform actually does:
# A passive list of desired resources
resource "aws_s3_bucket" "models" {
bucket = "my-project-models"
}
resource "aws_iam_role" "worker" {
name = "my-project-worker"
# ... more config
}
Then you run terraform apply. Terraform reads the list, makes resources exist to match, and exits.
Then... what? The list sits there. The resources drift. Someone manually edits a bucket policy in the AWS Console. A security group rule gets added for debugging. Terraform state gets out of sync.
So we add reconciliation loops:
# GitOps workflow
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: infra
spec:
interval: 5m # Check every 5 minutes
Every 5 minutes, the system wakes up and asks: "Does reality match my list?"
terraform plan. GitOps controllers watching for drift. DevOps engineers spending mornings fixing drift. This is reactive. The system detects drift and fixes it.
Let's be precise about terminology:
| Current Term | What It Actually Means | What It Should Be Called |
|---|---|---|
| Infrastructure as Code | Passive resource list + reconciliation | Infrastructure as a List |
| Infrastructure as a Library | Dynamic resource management via code | Infrastructure as Code (the true meaning) |
But "Infrastructure as Code" was taken. First mover advantage. So we need a new term for what true dynamic infrastructure should be:
Infrastructure as a Library (IaL)
Think about how you use a library in code:
use std::collections::HashMap;
fn main() {
// Create a HashMap
let mut map = HashMap::new();
map.insert("key", "value");
// Use it
let value = map.get("key");
} // HashMap is dropped here - memory automatically freed
Key properties:
Now imagine infrastructure working the same way:
use synkti_infra::Infrastructure;
async fn run_experiment() -> Result<()> {
// Create infrastructure
let infra = Infrastructure::new("my-experiment").await?;
// Use it
infra.spawn_instances(3).await?;
run_workload(&infra).await?;
} // Infrastructure automatically destroyed here
You BUY resources. You OWN them.
Accumulating infrastructure = Accumulating wealth.
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ Bucket │ │ Bucket │ │ Bucket │ │ Bucket │
│ #1 │ │ #2 │ │ #3 │ │ #4 │
│ 2019 │ │ 2020 │ │ 2021 │ │ 2022 │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
DevOps Team: "Our infrastructure has grown so complex.
We need MORE tools to manage it."
Problem: Resource accumulation, complexity explosion
You BORROW resources. You RETURN them.
Infrastructure is a dependency, not an asset.
fn run_job() {
let infra = Infra::new(); ┐
// ... use infra ... │ Scope (borrowed)
} │
┘ Auto-returned
Developer: "I just import Infra and use it.
It cleans itself up when I'm done."
Benefit: No accumulation, no complexity, no cleanup
| Aspect | Terraform (List) | IaL (Library) |
|---|---|---|
| Definition | Declarative list | Imperative code |
| Creation | Manual terraform apply |
Automatic in code |
| Lifetime | Permanent until manually destroyed | Scoped to code execution |
| Cleanup | Manual (terraform destroy) |
Automatic (RAII) |
| Drift handling | Reconciliation loops | No drift possible |
| State source | External (terraform.tfstate) | Internal (in-memory) |
| Mental model | Infrastructure = assets | Infrastructure = dependencies |
In C++, RAII (Resource Acquisition Is Initialization) ties resource lifetime to object scope. When an object goes out of scope, its destructor runs and resources are freed automatically.
// C++ RAII example
{
std::vector<int> v(1000); // Acquire memory
// Use v
} // Memory automatically freed (destructor runs)
The same principle applies to cloud resources:
// Rust RAII for cloud
{
let infra = Infrastructure::new("my-project").await?;
// Use infra (buckets, IAM, instances)
} // Infrastructure automatically destroyed (Drop runs)
The mapping is direct:
| C++ RAII | Cloud RAII |
|---|---|
new / malloc |
terraform apply / AWS SDK create |
| Use resource | Use S3, EC2, etc. |
delete / free |
terraform destroy / AWS SDK delete |
| Destructor | Drop trait |
| Scope exit | Variable dropped |
| Memory leak | Resource leak |
pub struct Infrastructure {
project: String,
owner: OwnerMarker, // RAII guard
}
impl Infrastructure {
pub async fn new(project: &str) -> Result<Self> {
// Create resources dynamically
let bucket = create_s3_bucket(&format!("{}-models", project)).await?;
let iam = create_iam_role(&format!("{}-worker", project)).await?;
let sg = create_security_group(&format!("{}-sg", project)).await?;
// Create owner marker (RAII guard)
let owner = OwnerMarker::create(project)?;
Ok(Self { project: project.into(), owner })
}
}
// RAII: Drop trait automatically cleans up
impl Drop for Infrastructure {
fn drop(&mut self) {
info!("Cleaning up infrastructure for {}", self.project);
// Destroy buckets, IAM, SGs
// Remove owner marker
}
}
// Usage
async fn run_experiment() -> Result<()> {
let _infra_guard = Infrastructure::new("experiment-123").await?;
// Do work
run_training().await?;
// Infra destroyed here when guard is dropped
Ok(())
}
The _infra_guard variable is never used, but its existence keeps the infrastructure alive. When it goes out of scope, cleanup happens.
There's an ethical dimension to this paradigm shift.
Infrastructure as Real Estate:
Infrastructure as a Library:
"As a distributed systems engineer, I have to respect the resources and not abuse them even a little."
RAII for cloud infrastructure is environmental responsibility:
Cloud computing changed everything, but our mental models didn't keep up.
1950s-2000s: Physical Infrastructure
You buy servers. You rack them. You own them. Accumulation makes sense. The server is an asset.
2006-now: Cloud Infrastructure
You don't own anything. You rent everything. But we still think like we're buying assets.
The future: Infrastructure as a Library
Resources are borrowed, scoped, returned. Infrastructure is a dependency, like any other library. The application owns the lifetime, not the operations team.
This matters because:
The shift from "Infrastructure as a List" to "Infrastructure as a Library" is more than terminology. It's a paradigm shift in how we think about cloud resources.
Infrastructure should work like any other library dependency: you import it, you use it, it cleans itself up when you're done. No reconciliation loops. No drift. No forgotten resources accumulating bills.
"Respect the resources. Don't abuse them even a little."
This is how infrastructure should work in the cloud era. Not as assets you accumulate, but as dependencies you borrow, use, and return.