DevOps hiring guide

Adopting infrastructure as code without a rewrite

Importing everything you already run into Terraform is the version of this project that fails. It produces months of work, a state file nobody trusts, and a plan output that proposes to destroy a production database because an attribute was described slightly differently in code than in the console. The estate that benefits from being coded is the part that changes, and in most companies that is a minority of what exists.

Do you have to import everything?

No, and deciding not to is the choice that makes the project finishable. Infrastructure as code earns its cost through repetition: resources that get created repeatedly, changed frequently, or need to exist identically in more than one place. A network built once six years ago and touched twice since returns almost nothing for the effort of importing it, and carries real risk while you do.

The alternative to importing is referencing. Most tools can read an existing resource without managing it, so new coded resources attach to the old network, the old cluster and the old database without those becoming your responsibility to describe correctly. This gives you the benefit at the edge where work is happening while leaving the archaeology alone.

The test for whether something is worth importing is how many times it has changed in the last year. If the answer is zero or one, leave it referenced and revisit when it next needs to change, at which point coding it is a smaller job because you are already in there.

Which resources are worth coding first?

The ones with a high change rate and a low blast radius, which is a narrower set than the usual advice implies. The order below reflects what tends to survive the first year rather than what makes the most complete diagram.

Resource typeImport now?Reasoning
IAM roles, policies and service accountsYes, firstChange constantly, drift is a security problem, and review value is highest here
DNS recordsYesCheap to import, changed often, and a mistake is quickly reversible
Per-service compute and deployment configurationYes, as a reusable moduleThis is where repetition lives, and where a template pays back every new service
Cluster add-ons: ingress, autoscaler, certificate managementYesUpgraded on a cadence, and reproducing them by hand is how clusters diverge
Core networking: VPCs, subnets, peeringNot yet, reference itRarely changes, largest blast radius, and the import is fiddly
Databases and stateful servicesReference, or import with deletion protection onAn accidental replacement is unrecoverable, unlike every other row here

What actually breaks during adoption?

State, in three specific ways. The first is drift: someone changes a resource in the console during an incident, and the next plan proposes to revert it, usually at an inconvenient moment and usually without anyone remembering why the manual change was made. The second is concurrency, where two people or two pipelines apply at once and one overwrites the other's understanding of reality.

The third is the one that causes lasting damage. Some attributes cannot be changed in place, so a small difference between your code and the live resource results in a plan that destroys and recreates it. For a security group that is a brief outage. For a database it is a resume-generating event. Reading every plan before applying is not bureaucracy in the first year, it is the control that prevents this.

Provider upgrades produce a milder version of the same problem, where a new major version changes a default or renames an attribute and suddenly proposes changes to resources nobody touched. Pin provider versions from day one, upgrade deliberately, and read the plan afterwards rather than assuming an upgrade is inert.

How do you stop people changing things in the console?

Not immediately, and pretending otherwise is why adoption programmes stall. During an incident, someone with production access will make a change by hand, and that is usually the correct decision at the time. A policy that forbids it will be broken quietly, which is worse than one that expects it and handles the aftermath.

The workable arrangement has three parts. Default access to production becomes read-only, with an elevated role that anyone can assume and that records who assumed it and when. Drift detection runs on a schedule and reports rather than corrects, so a manual change surfaces the next morning rather than in a surprise plan three weeks later. And the incident follow-up includes a line for reconciling whatever was changed by hand.

That combination changes the behaviour without a confrontation. People are not being prevented from acting; they are being asked to leave a trace, and the trace is what turns an undocumented divergence into a small ticket.

Should the pipeline apply automatically?

Not at first, and possibly never for the resources with the largest blast radius. The sequence that works is plan on every pull request with the output visible in the review, apply manually with a human reading the plan, and only then automate applies for the categories that have proven boring: DNS records, service deployments, IAM changes that a policy check has already validated.

The reason to move slowly is that infrastructure code has a property application code does not. A bad application deploy is rolled back; a bad infrastructure apply may have already deleted the thing you would roll back to. Automation of the apply step multiplies the speed at which that can happen, which is a benefit only once the review process is catching problems reliably.

The practical checkpoint is your plan output. If plans routinely contain changes nobody intended, automatic apply will act on them, and the correct response is to fix why the plans are noisy rather than to add an approval step that people will click through.

How do you know the adoption worked?

Build an entire environment from scratch, in an empty account or a new region, using only what is in the repository. Time it, and note every point at which someone has to open a console or ask a colleague. That exercise is the only honest measure of whether the estate is described in code, and it is uncomfortable enough that most teams avoid it, which is why most teams do not know the answer.

The second measure is who can make a change. If an infrastructure change is a pull request that a developer can raise, that a reviewer can understand from the plan, and that gets applied the same day, the adoption has delivered what it was for. If changes still route through one person because only they can interpret the code, you have moved the bottleneck into a repository rather than removed it.

Neither of these is a percentage of resources coded, and that metric is worth actively avoiding. Coverage counts reward importing the easy static resources and say nothing about whether the estate can be rebuilt, which is the property you were buying.

Common questions

Do you have to import all existing infrastructure into Terraform?
No, and attempting it is the usual reason these projects fail. Infrastructure as code pays back on resources that change often or need to exist identically in several places. Static resources such as a network built years ago and rarely touched can be referenced as data sources instead, so new coded resources attach to them without your team taking on responsibility for describing them correctly.
What should you put into infrastructure as code first?
Start with IAM roles and policies, DNS records, per-service compute configuration and cluster add-ons. These change frequently, benefit most from review, and a mistake in any of them is quickly reversible. Leave core networking referenced rather than imported, and treat databases with particular caution, because an unintended replacement of a stateful resource is the one failure in this category that cannot be undone.
What is drift in infrastructure as code?
Divergence between what the code describes and what actually exists, usually created by a manual change made during an incident. It surfaces later as a plan proposing to revert something, often at an awkward moment and without anyone remembering why the manual change happened. Scheduled drift detection that reports rather than corrects turns this into a next-morning ticket instead of a surprise during an unrelated deployment.
Should infrastructure changes apply automatically from the pipeline?
Not initially. Run the plan on every pull request so reviewers see it, and keep the apply step manual until plans are consistently free of unintended changes. Infrastructure differs from application code in that a bad apply may delete the thing you would have rolled back to. Automate applies later, category by category, starting with the ones that have proven uneventful such as DNS and service deployments.
How do you measure whether infrastructure as code adoption succeeded?
Rebuild a complete environment in an empty account or new region using only the repository, and record every point where somebody has to open a console or ask a colleague. Then check who can raise an infrastructure change: if it is a pull request a developer can open and a reviewer can approve from the plan, the bottleneck is gone. Percentage of resources coded is a misleading metric and rewards the wrong work.

More on DevOps engineers

Let’s create something out of this world together.

Have a project in mind? Contact us for expert design and development solutions. Let’s discuss how we can help grow your business.

Azaadi Offer

Claim a free security assessment

Until 31 August we're covering the cost of a full vulnerability assessment and penetration test. Mention it in your message and we'll scope it with you.

  • Web application testing, authenticated and unauthenticated
  • Mobile application testing across iOS and Android
  • External network and infrastructure assessment
  • Manual exploitation by engineers, not scanner output

Testing and the report are free. Fixing what we find is quoted separately, with no obligation to accept.

Read the full offer

Tell us what you are trying to build and we will tell you plainly whether we are the right people for it. Book a call with an expert to work through the detail, or ask for a fixed quote if the scope is already clear. No obligation either way.

Four fields is all we need to get started.

Fastnexa Logo

© 2026 fastnexa. All rights reserved.