All articles

Infrastructure as Code with Terraform: A Guide for Growing Teams

Why teams move cloud setup from the console into Terraform, how to handle state safely, structure modules and environments, review plans in CI, bring existing resources under control, and where OpenTofu fits.

DevOps|Published |10 min read
City lights across the Earth at night seen from orbit

Most cloud accounts start the same way. Someone creates a server, a database, and a few security groups in the web console, and it works. Two years later nobody remembers why port 8080 is open, staging differs from production in ways nobody can list, and rebuilding the environment after an incident would take days of guessing. Infrastructure as code fixes this by describing the setup in files that live in Git. Terraform is the most widely used tool for it.

What You Get From Infrastructure as Code

  • Every change is a pull request, so you can see who changed what and why, and roll back.
  • Staging and production are built from the same code, so they stay alike.
  • A new environment for a client or a region takes an hour instead of a week.
  • The code is documentation that never goes out of date.
  • Security review can happen before a change is applied rather than after an incident.

How Terraform Works

You describe resources such as a VPC, a database, or a DNS record in HCL files. Providers translate those descriptions into API calls for AWS, Google Cloud, Azure, Cloudflare, Kubernetes, and hundreds of other services. terraform plan compares the code with what exists and shows exactly what will be created, changed, or destroyed. terraform apply makes those changes. Terraform records what it manages in a state file, which is how it knows that a resource in the code is the same one that already exists in the cloud.

Treat State as Sensitive and Shared

The default local state file breaks as soon as two people work on the same infrastructure. Move it to a remote backend on day one, such as an S3 bucket, Google Cloud Storage, or Terraform Cloud. Turn on locking so two applies cannot run at once. Since Terraform 1.10 the S3 backend can lock with a lock file in the bucket itself, without a separate DynamoDB table. State often contains secrets such as database passwords in plain text, so encrypt the bucket, enable versioning, and limit who can read it.

Structure Code With Modules and Separate Environments

ApproachHow it worksWhen it fits
One directory per environmentenvs/staging and envs/production each have their own state and call shared modules with different variablesMost teams. Clear separation, and a mistake in staging cannot touch production state
Terraform workspacesOne configuration with several named states selected by terraform workspace selectMany short-lived copies of the same setup, such as preview environments
Separate accounts or projects per environmentEach environment also lives in its own cloud account with its own credentialsProduction systems where access must be strictly separated

Put reusable pieces such as a standard VPC, a database with backups and alarms, or a service with its load balancer into modules with clear inputs and outputs. Pin module and provider versions so an upgrade happens on purpose. Keep each state reasonably small. A single state holding everything makes plans slow and every apply risky.

Run Terraform From CI

  1. 1On each pull request, run terraform fmt -check, terraform validate, and a security scanner such as Checkov or Trivy.
  2. 2Run terraform plan and post the output as a comment so reviewers see the real effect of the change.
  3. 3Pay attention to any resource marked for replacement or destruction. A renamed resource can mean a deleted database.
  4. 4After approval and merge, apply the saved plan from CI, using short-lived cloud credentials through OIDC instead of long-lived access keys.
  5. 5Block manual changes in the console for production, or at least alert on them.

Bring Existing Infrastructure Under Control

You rarely start from an empty account. Terraform 1.5 added import blocks, and terraform plan -generate-config-out can write a first draft of the configuration for resources you import. Start with low-risk pieces like DNS records and buckets, clean up the generated code, and move on to networks and databases once the team is comfortable. Run plan regularly afterwards. Any difference it reports on code nobody changed is drift from manual edits.

Terraform or OpenTofu?

In 2023 HashiCorp moved Terraform from an open source licence to the Business Source License. The community forked the last open source version as OpenTofu, now maintained under the Linux Foundation. For a company using Terraform to manage its own infrastructure, the licence change usually does not matter. OpenTofu is a reasonable choice if you want an open source licence or a feature it offers, such as built-in state encryption. The two tools still share most syntax and providers, but they are slowly diverging, so pick one per codebase.

If a change to production cannot be reviewed in a pull request, it is one more thing someone has to remember.

We help teams move existing cloud accounts into Terraform without downtime, and our DevOps training includes hands-on Terraform labs with remote state, modules, and CI pipelines.

Key takeaways

  • Infrastructure as code turns cloud changes into reviewed, repeatable pull requests.
  • Use a remote, encrypted, versioned, and locked backend for state from the first day.
  • Separate environments into their own states and share code through versioned modules.
  • Review terraform plan in CI and watch for replacements and deletions.
  • Import existing resources gradually and run plan regularly to catch drift.

Related articles

More articles on software development, AI, cloud, and infrastructure.

Hands sorting printed tax forms and receipts next to a calculator
AI Development|

Automating Document Data Entry With AI: Invoices, Receipts, and Forms

How AI reads invoices, receipts, ID cards, and forms and turns them into structured data, how OCR and large language models fit together, why validation and human review still matter, how to measure accuracy, and what to watch for with personal data.

Aerial view of a busy container port with cranes and stacked shipping containers
DevOps|

Deploying Applications to Kubernetes With Helm: A Practical Guide

What Helm charts are, how values and templates work, how to structure a chart for several environments, upgrade and rollback safely, keep secrets out of Git, test charts in CI, and decide between Helm and Kustomize.

Looking for a software development partner?

Tell us about your project, what you need to build, and the challenges you are facing. We can discuss the technical approach, scope, timeline, and estimated cost.

Start a conversation