Every once in a while I send hand picked things I've learned. Kind of like your filter to the tech internet. No spam, I promise!
Share
AI Can Write Your Terraform. You Still Own the Blast Radius.
Published about 8 hours ago • 6 min read
AI Can Write Your Terraform. You Still Own the Blast Radius.
This issue is brought to you by:
18 Kubernetes agentic AI security best practices
CNCF and Teleport lay out the top cloud-native agentic standards that you should know before you deploy autonomous AI agents in your Kubernetes clusters.
I can ask an agent to generate a cloud environment and get hundreds of lines of Terraform back in seconds. I promise it's going to be BEAUTIFUL. It also means I can produce a very expensive mistake faster than ever. So yes, I think knowing Terraform is becoming more important even if (or - BECAUSE) AI writes most of it. Someone still needs to understand which account those resources belong in, what depends on what, and why a seemingly innocent change wants to replace a server. The cloud bill does not care who wrote the code. Here's the workflow I want engineers to understand before handing infrastructure changes to an agent ->
Describe the infrastructure, understand the dependencies
Terraform is an infrastructure as code (IaaC) tool. You describe the resources you want using HCL, and Terraform works out the operations needed to move managed infrastructure toward that configuration.
A provider handles the interaction with a particular API. For AWS, that means using the AWS provider to manage resources such as EC2 instances, networks, and IAM roles.
The configuration often starts in main.tf, but that filename has no special power. You can split the same module across files for networking, compute, permissions, and outputs.
Dependencies come from references between resources. If an instance references a subnet, Terraform can understand that relationship and order the relevant operations.
output value references the instance id
This is where understanding the configuration matters more than typing it. An agent can make an error disappear by adding a VPC (Literally setting an entirely new network with dozens of paid components). Whether that VPC belongs in your architecture is a separate question...
Make the configuration reusable, deliberately
Three building blocks make a small configuration easier to reason about:
Variables accept inputs, such as an instance type or a name.
Data sources look up information, such as an existing network or an Amazon Machine Image.
Outputs expose useful results, such as the ID of the instance you created.
I use variables for instance types, names, and tags rather than hardcoding them into resources. Just like in code - that lets someone reuse the configuration and override the inputs without editing the resource definitions.
Data sources also deserve some thought. Looking up the latest matching Linux AMI avoids copying an image ID by hand. But when that lookup resolves to a newer image, a later plan may propose replacing your instance.
For a disposable experiment, that might be convenient. For a production system, I want image upgrades to be intentional and reviewed.
Outputs are useful beyond the final success message. Scripts can consume them, and other infrastructure layers can use deliberately exposed values. Those connections become part of your system's design, so keep them small and understandable.
Data object that fetches the latest linux image by amazon
Variables can be referenced or overridden
Initialize, format, validate
These commands assume an existing, complete configuration and working cloud credentials. They are a workflow, not a standalone EC2 deployment recipe. Start with:
terraform init terraform fmt terraform validate
init prepares the working directory, initializes the backend, and downloads the providers and modules the configuration needs. Run it again when relevant backend or dependency configuration changes.
fmt makes the formatting consistent. In CI, terraform fmt -check can report formatting problems without rewriting files.
validate checks the configuration's syntax and internal consistency. It does not establish that your credentials work, your cloud quotas are sufficient, or your network design makes sense.
Commit .terraform.lock.hcl. It records provider selections and checksums so your team can reproduce those selections. It does not lock every dependency, and remote module versions still need deliberate management.
The downloaded working directory under .terraform/ belongs outside Git. So do state files and saved plans. We'll get to why those last two matter shortly.
Read the plan before touching the cloud
This is the part I would NOT outsource blindly:
terraform plan -out=tfplan
Read the proposed additions, changes, and destructions. Then read the actual resource differences. A reassuring total at the bottom doesn't tell you whether the change belongs in the correct environment.
Pay particular attention to replacements. Changing a tag might update an instance in place. Changing another attribute might require destroying the existing instance and creating another.
Some values will remain unknown until apply. That is normal, but it is also a reason to understand the references that produce them.
When the saved plan is approved, apply that plan:
terraform apply tfplan
The saved-plan workflow applies those planned actions without another approval prompt. Treat the command as the deployment step, not another preview.
A plain terraform apply ("tf apply" after "tf plan") creates a fresh plan and normally asks for approval. That's convenient interactively, but the saved-plan workflow makes the connection between review and execution clearer. Most engineers I've seen are actually doing that, instead of planning and executing the plan, in all honesty, there isn't a huge difference in most use cases.
Plans can still fail during execution. Permissions, quotas, and changes outside Terraform can interfere. After a failure, inspect what happened and generate a fresh plan before continuing. Don't keep feeding errors to an agent until something turns green. Again, an agent will solve this in the quickest way it sees. Kind of like asking AI to solve world hunger and it decides to wipe out humanity. Easy fix isn't it?
Protect state like operational data
Terraform state maps resource addresses in your configuration to real infrastructure objects and stores attributes Terraform needs to manage them.
Lose that mapping and you have a serious management problem. Leak it and you may have a security problem too: state can contain secrets. Saved plan files can also contain sensitive information.
Never commit either to your repository. Marking a value sensitive hides it from some displays; it does not magically remove it from state.
For a team, use a properly secured remote backend with access controls, encryption, versioning or backups, and supported locking.
On modern Terraform, the S3 backend supports native lockfiles when you opt in with use_lockfile = true.
Locking helps prevent concurrent writers from stepping on each other. It doesn't stop someone from changing a resource directly in the cloud console. Those changes can introduce drift, which subsequent plans need careful review to reconcile.
After applying, you can retrieve a declared string output for a script:
terraform output -raw instance_id
That's useful, but it reads the stored output. For an operational check, inspect the actual resource through the provider's console or API too.
Clean up deliberately
For a disposable environment, Terraform makes teardown much easier:
terraform destroy
Check the account, workspace, backend, and destruction plan before approving. This can remove real infrastructure and data.
Terraform uses its dependency relationships to order deletion of the resources it manages. It does not promise to clean up every resource in your account, including things created separately or no longer tracked in state. Deletions can also fail.
I like reproducible cleanup. I like verifying the cleanup even more.
Terraform or OpenTofu?
HashiCorp released Terraform in 2014. In 2023, its move to the Business Source License prompted the OpenTofu fork, now under the Linux Foundation. IBM acquired HashiCorp in 2025.
I lean toward OpenTofu for its open-source governance. The familiar configuration language and workflow make it approachable if you already know Terraform.
But having the same family roots is not a guarantee that every version, feature, provider, and backend combination is interchangeable. Follow the official OpenTofu migration guide, back up state, and check compatibility for your versions. Never delete state as a migration shortcut. Initialize with OpenTofu, inspect its plan, and stop if it proposes unexpected changes. All that said, there's a BIG chance you don't actually have to do anything and can move over to opentofu seamlessly.
Whichever tool you choose, learn to :
read the configuration
challenge the plan
protect the state
RCP! BOOM. Did I just coin the best practice AI handler buzzword?
AI can save you a lot of typing. I'd spend some of that saved time understanding exactly what you're about to deploy.
I hope this was valuable! Thank you for reading. Feel free to reply directly with any question or feedback. Have a great weekend!
Stop Using Elasticsearch. Use Postgres Instead This issue is brought to you by: Postgres for sensor and machine data Factories, wells, grids, and fleets run on live machine data. Tiger Data keeps it performant and scalable in one Postgres. Get started with Text Search on TigerData→ Do you still need Elasticsearch? I wanted to test that properly, so I put Postgres in Docker, loaded it with thousands of support tickets, and checked how far the same BM25 relevance search used by dedicated search...
Somehow, Atuin Just Got EVEN Better This issue is brought to you by: Give your AI agents memory Learn how Oracle Agent Memory handles persistent context with custom extraction, hybrid search, filtering, and more control over what your agents remember. Read the developer guide → There aren't many terminal utilities I'd take with me anywhere. But if I had to pick just one, Atuin may very well be it. I've been using it for a few years now, and somehow the magic turtle keeps getting better. It...
You’ve Never Seen a Shell Like Xonsh This issue is brought to you by: Redis Iris: Your agents should be getting smarter Unreliable agents fail in production. Redis Iris is a unified, real-time context engine that delivers fresh, relevant context so agents perform at scale. Try for FREE Tell me if this sounds familiar:You start with a quick shell script. Then one step gets annoying, so you call Python. Then Python needs to shell out again. Then you’re parsing strings, juggling quoting, and...