Helm7

Infrastructure as Code for Beginners

The Helm7 team · Published 20 September 2026 · Checked 30 September 2026 · 7 min read

infrastructure as code: architectural blueprints and a pencil on a wooden desk
Photo by Ron Lach on Pexels

Infrastructure as code sounds like a tooling topic, but the skill that matters is reading a plan. One line in that plan can say a database will be destroyed and rebuilt, and you would rather learn that before you press apply. This guide starts from a plan, then covers the tools, the state file and a first week that will not hurt anything.

In short

  • Learn to read a plan first. A -/+ line means destroy and recreate, and it is where outages start.
  • Infrastructure as code makes infrastructure reviewable: a change is a diff, not a memory of a click.
  • Terraform and OpenTofu use HCL. Pulumi lets you write TypeScript, Python, Go, C#, Java or YAML.
  • Save plans and apply the exact file, guard critical resources with prevent_destroy, and use remote state with locking once you are two people.
  • Start with one low-stakes resource and import existing infrastructure gradually.

Read this plan before you learn anything else

Here is an abridged plan for a worked example. It is illustrative, and the values are made up. Somebody changed the name of a database in a Terraform file, ran terraform plan, and got this.

Terraform will perform the following actions:

  # aws_db_instance.main must be replaced
-/+ resource "aws_db_instance" "main" {
      ~ identifier = "shop-db" -> "shop-database" # forces replacement
      ~ endpoint   = "shop-db.example.rds.amazonaws.com" -> (known after apply)
    }

Plan: 1 to add, 0 to change, 1 to destroy.
Illustrative plan output, abridged. The symbols and the summary line follow the format in HashiCorp's tutorials

The whole point of infrastructure as code is in the last line. One to add and one to destroy is not a rename. It is a new empty database and the death of the old one. The name change looked harmless in the file. The plan shows what it really does.

How to read a Terraform plan, from HashiCorp's tutorial
SymbolMeaningHow worried to be
+CreateCheck the cost
~Update in placeUsually fine
-DestroyStop and read
-/+Destroy, then create a replacementStop and read twice

What is infrastructure as code?

“Terraform is an infrastructure as code tool that lets you build, change, and version cloud and on-prem resources safely and efficiently.”
HashiCorp, Terraform documentation, Introduction

That covers the idea. Instead of clicking a server, a database and a load balancer into existence in a cloud console, you write a file that says what should exist. A tool compares the file with what is running and makes the two match.

Automation is a side effect. The real gain is that your infrastructure becomes reviewable. A change is a pull request. A diff shows what will happen. Six months later, the history says who changed what and why, and it does not depend on anyone remembering a click.

Which infrastructure as code tool should you pick?

Three names cover most beginner questions. They work the same way underneath. You describe the state you want, the tool plans the difference, and applying the plan changes real things. What differs is how you write it and who looks after it.

Three common infrastructure as code tools, using each project's own descriptions
ToolYou writeLooked after byEcosystem figure
TerraformHCL, its own configuration languageHashiCorpThousands of providers
OpenTofuHCL, as a drop-in replacement for TerraformThe Linux Foundation, MPL-2.0 licence3,900+ providers, 23,600+ modules
PulumiTypeScript, JavaScript, Python, Go, C#, Java or YAMLPulumiNot stated

For a beginner the language matters less than the community. Pick the one whose examples you keep finding when you search for your problem. If your team lives in TypeScript, Pulumi will feel natural. If you want the widest set of examples, Terraform or OpenTofu is the safer bet. We compare the two head to head in Terraform vs Pulumi.

Why does a dry run prevent outages?

“The terraform plan command creates an execution plan, which lets you preview the changes that Terraform plans to make to your infrastructure.”
HashiCorp, Terraform CLI documentation, terraform plan

That preview is most of the safety in the whole practice. It turns "I hope this is fine" into a list somebody else can review. Three habits make it work.

  • Read every line marked - or -/+ each time, not only when you remember. Most incidents come from a replace nobody spotted.
  • Save the plan and apply that exact file. terraform plan -out writes it, and terraform apply takes it, so what you approved is what runs. Treat the file as sensitive: HashiCorp warns that sensitive values are saved in cleartext inside it.
  • Guard the things you cannot lose. Setting prevent_destroy to true makes Terraform reject any plan that would destroy that resource. It is not a lock, though. The docs note that removing the resource's configuration bypasses it.

Two more pitfalls catch beginners. The first is drift. Somebody fixes something by hand during an incident, and the file no longer matches reality. Terraform has a refresh-only plan for this. It updates state to match changes made to remote objects outside of Terraform, so you see the difference before you decide which side is right. The second is the replace itself. The create_before_destroy rule tells Terraform to build the replacement first and remove the old resource afterwards. It suits things like a server behind a load balancer. The docs add a caveat: it stops a destroy-time provisioner from running. It also does not rescue a database, because a new empty database is still empty.

A first week that will not hurt anything

  1. 1Pick one low-stakes resourceA storage bucket, a DNS record or a small test server. Not your production database. You are learning the loop, not migrating.
  2. 2Write it, then run init and planterraform init downloads the provider. terraform plan shows a single + line. Read it aloud to a colleague if you can.
  3. 3Apply, then change one argument and plan againRename a tag and watch a ~ appear. Then change something that forces replacement and watch -/+. Seeing both in a safe place is worth an hour.
  4. 4Move state somewhere sharedA local state file is fine for one person on day one. The moment a second person joins, use a remote backend with locking.
  5. 5Put plan in your pull requestsRun terraform plan with -detailed-exitcode in CI. Exit code 0 means no changes, 1 means an error, and 2 means there are changes to review.
  6. 6Import what already exists, slowlyBring hand-made resources under management one at a time. Importing the whole estate in one go is how people end up with a plan nobody trusts.
Exit codes from terraform plan with -detailed-exitcode, from HashiCorp's CLI reference
Exit codeMeaningWhat your pipeline should do
0Succeeded, no changesCarry on
1ErrorFail the build
2Succeeded, changes presentPost the plan for review

What is state, and why do teams fall out over it?

The state file is how Terraform remembers what it built. HashiCorp describes it as a source of truth for your environment, and the tool uses it to work out the changes needed to match your configuration. Lose it or corrupt it, and the tool no longer knows what exists.

“When working with Terraform in a team, use of a local file makes Terraform usage complicated because each user must make sure they always have the latest state data before running Terraform and make sure that nobody else runs Terraform at the same time.”
HashiCorp, Terraform documentation, Remote state

That is the whole case for a remote backend. Shared state means everyone plans against the same picture, and state locking stops two people applying at once. Set it up early. Moving state later is possible but fiddly.

When is infrastructure as code overkill?

Honestly, sometimes. One app on one platform, changed twice a month by one person, can live happily on a dashboard. The file starts to pay off when you have several environments, several people, or changes you want reviewed.

There is a middle path. Some platforms build the plan into the platform, so you get the preview without owning a Terraform project. The team-level version of the same idea is covered in what an internal developer platform is.

The same idea on a hosting platform

Helm7 applies the plan habit to its own API. Every operation that changes infrastructure takes dry_run set to true and returns the ordered changes, a monthly cost band, the largest cost by name, and a plain list of anything that could not be undone. Destructive operations refuse to run until confirm is set. It works the same for a person at a terminal and for an AI agent. See how agents use it and the dry-run deployment plan for the detail.

Common questions

  • Is infrastructure as code only for large teams?

    No. A solo developer benefits from a reviewable plan and from having infrastructure in a file rather than in a console. The benefits grow with the number of environments and people, but they start at one.

  • Do I have to choose between Terraform and Pulumi for the whole company?

    Most teams standardise on one, because state handling and tooling differ. Nothing stops you trying both on a small project first. OpenTofu is a further option, described by its project as a drop-in replacement for Terraform.

  • What does a dry run actually check?

    It compares your declared configuration with the current real state and lists what would be created, changed or destroyed to reconcile the two. It makes none of those changes.

  • What does the -/+ symbol in a Terraform plan mean?

    It means destroy and then create a replacement. Some changes, such as renaming a database or moving an instance to a new network, cannot be made in place. Read every -/+ line carefully, because data may not survive it.

  • Can infrastructure as code estimate cost before I apply?

    A plain terraform plan lists changes, not prices, so you check cost separately. Some platforms build a monthly cost estimate into their own dry run. The Helm7 API does, returning a cost band with every plan.

Sources

  1. HashiCorp: Terraform introduction
  2. HashiCorp: terraform plan command
  3. HashiCorp: Terraform remote state
  4. HashiCorp: resource lifecycle meta-arguments
  5. OpenTofu
  6. Pulumi documentation: IaC concepts

Run your entire app stack, end to end, from $12 a month.

App, Postgres, auth, storage, jobs and domains on one platform, planned and priced before anything changes.

More from the blog