TrademarkTrademark
Features
Documentation
Comprehensive Guide

Infrastructure as Code With AI Coding Agents: A Practical Primer

A practical guide to using AI coding agents with Terraform and OpenTofu without losing control of context, state, or the apply boundary.
Ryan FeeJuly 10, 2026
Key takeaways
  • An AI coding agent changes how Terraform or OpenTofu work is performed, but it does not change the plan, apply, state, and locking model. The reviewed plan remains the safety boundary.
  • Registry-only MCP servers provide current provider and module documentation without control-plane access. State-aware servers may read run logs, variables, outputs, or resource inventory, while write-capable servers can create runs or change infrastructure.
  • Tool definitions and raw IaC output compete for the same context window as the task. Anthropic has measured 55,000 tokens of definitions in a 58-tool setup, while current Claude Code warns when one MCP result exceeds 10,000 tokens.
  • Keep one task in each session, load tools on demand, delegate noisy investigation to read-only subagents, write large outputs to protected files, and clear or compact context at phase boundaries.
  • Start with read-only cloud and control-plane credentials plus a least-privilege, plan-capable backend identity. Deny apply, destroy, state writes, force-unlock, and lock bypass; keep approval and apply outside the agent by default.

An AI coding agent can inspect a module, look up a provider argument, edit HCL, run tests, and produce a plan in one working loop. Connect it to an MCP server and it may also see private modules, failed runs, drift, workspace settings, or the live infrastructure control plane.

That reach is useful, but it joins two systems that both carry hidden state. Terraform or OpenTofu has configuration, provider versions, a selected workspace, credentials, and state. The agent has instructions, tools, retrieved files, tool results, and a finite context window. Reliable work depends on controlling both.

This primer is for engineers who know Git and cloud infrastructure but are new to running Terraform or OpenTofu through Claude Code or a similar agent. It covers the IaC fundamentals only where they explain an agent failure mode.

Source and version note: This article was researched on July 10, 2026. Undated product documentation linked below is living documentation accessed on that date. Terraform v1.15.8, released July 8, 2026, was the current stable release. OpenTofu v1.12.3, released June 18, 2026, was current and included a security fix for earlier 1.12 releases. The HashiCorp Terraform MCP server v1.0.0 was released June 9, 2026. Recheck versions and tool lists before copying a command or permission policy.

What Does an AI Agent Need to Know About IaC?

Infrastructure as Code stores a desired infrastructure definition in version-controlled files. Terraform and OpenTofu read that configuration, ask providers about remote objects, and build a dependency graph of proposed actions. The common workflow is write, plan, review, and apply. The full introduction is covered in What is Terraform?; the important part here is where the agent can be wrong.

A normal plan refreshes its view of remote objects, compares configuration with prior state, and proposes creates, updates, replacements, and deletes. Terraform Core does not perform those proposed resource lifecycle changes during planning. The state snapshot maps configuration addresses such as module.network.aws_vpc.main to real object identities and records metadata and cached attributes. HashiCorp documents both the planning sequence and state's mapping role.

That is narrower than saying nothing can happen during a plan. Planning loads provider binaries and reads data sources. HashiCorp's official external data source can run a local program and passes it the Terraform process environment. Treat planning an untrusted repository as code execution: review dependency-lock and module-source changes, pin provider selections, restrict credentials and network access, and use a sandbox. Inspect external data sources before planning, and inspect provisioners and Terraform actions before applying.

The plan is a point-in-time result, not a promise. Another run or a console change can make it stale. The selected workspace, cloud account, region, input variables, provider versions, or backend can also be wrong while the HCL itself looks correct. An apply that fails can still leave partial changes: HashiCorp's apply tutorial says Terraform records completed changes and exits on an error; it does not roll the earlier changes back automatically.

That leads to three rules for agent work:

  1. The agent must identify the execution context before interpreting a plan: engine and version, working directory, backend, workspace, account or subscription, region, variables, selected provider versions, and exact module version constraints.
  2. A person or controlled pipeline must review the final plan that will be applied. Supplying a saved plan to terraform apply counts as approval and skips the interactive prompt; -auto-approve removes it too. Those behaviors are documented in the apply reference.
  3. State and plan artifacts are secrets-bearing data. sensitive = true hides values in normal output but does not remove them from state or saved plans. terraform show -json displays sensitive state values in plain text, and OpenTofu gives the same warning for sensitive state.

Remote state and locking still matter when an agent is the operator. A backend may lock state before a write, but locking is optional and backend-dependent. Disabling locking or force-unlocking another writer can create competing state writers. The official Terraform and OpenTofu guidance both treat force-unlock as recovery for your own failed lock, not a way around contention.

How Do AI Coding Agents Interact With Terraform and OpenTofu?

Most coding agents work across three surfaces.

The first is the repository and shell. The agent reads .tf files, module tests, CI configuration, .terraform.lock.hcl, and project instructions. It can run fmt, validate, and plan. It may also be able to run test, apply, destroy, state pull, or state rm if the shell has suitable credentials. A registry-only MCP connection does not make that shell read-only.

Do not group test with non-applying checks. Both terraform test and tofu test can create real infrastructure and attempt cleanup; cleanup can fail. Inspect every test file first. Under a no-apply policy, run only tests that the team has verified as plan-only or safely mocked. Apply-mode tests need explicit authorization, a disposable test account, and monitored cleanup.

The second surface is reference data. An MCP registry server can retrieve current provider and module documentation. The local CLI can also emit the installed providers' machine-readable type information with terraform providers schema -json. Documentation and schema are related but different: registry Markdown explains use and examples, while the schema describes attribute types, nesting, and whether values are required, optional, computed, or sensitive.

The third surface is the infrastructure control plane. Platform MCP servers may expose organizations, projects, workspaces, variables, runs, logs, plan JSON, drift, outputs, state-derived resource inventories, and write operations. MCP itself defines how a host connects to servers that publish tools, resources, and prompts. The server's credentials still determine what the resulting tool call can see or change.

The useful access model has five classes:

Class What the agent can reach Typical risk
Registry reference Public provider and module documentation Wrong version or bad generated HCL, but no infrastructure mutation through that server
Control-plane read Runs, logs, outputs, variables, drift, workspace metadata, or resource inventory Secret and topology disclosure; large payloads entering model context
Raw-state read A state snapshot through show, state pull, or a platform download Broad plaintext secret and topology disclosure without a state write
Control-plane write Workspace or variable changes, run creation, apply approval, or direct resource lifecycle calls Infrastructure and state can change under the caller's identity
State or lock change state push, state rm, state mv, state replace-provider, import, taint or untaint, or force-unlock Highest recovery burden; an incorrect state change can orphan or duplicate objects, while force-unlock can enable a competing writer

"State-touching" is therefore shorthand, not a binary property. Reading an output is different from downloading raw state; a refresh run is different from state push; starting an apply is different from editing the state file directly. Permission reviews should preserve those distinctions.

Which MCP Servers Exist for Terraform and OpenTofu?

The following table covers representative first-party servers with published documentation as of July 10, 2026. It is not a complete MCP catalog, and the tool lists have been changing quickly.

Server What it exposes now Access class and recent change
HashiCorp Terraform MCP server Public provider, module, and Sentinel policy docs; optional private registry; optional HCP Terraform or Terraform Enterprise organizations, workspaces, variables, runs, plan JSON, logs, policy sets, and stacks Hybrid. In v1.0.0, the executable defaults --toolsets to all, which includes the registry, private-registry, and HCP Terraform or Terraform Enterprise toolsets. Use --toolsets=registry or --toolsets=default for registry-only access. The action_run tool also requires ENABLE_TF_OPERATIONS=true; create_run retains limited run types when that flag is false. v1.0.0 shipped June 9, 2026, followed by the GA announcement on June 11. No generic raw-state edit tool is documented.
OpenTofu Registry MCP server Search plus provider, module, resource, and data-source details from the OpenTofu Registry Registry-only. Its five documented tools do not access workspaces, runs, plans, applies, or state. v1.0.0 was released June 6, 2025 and announced with OpenTofu 1.10 on June 23, 2025.
Scalr MCP server Environments, workspaces, run metadata and logs, policy results, modules, variables, drift, IAM, and provider, resource, version-usage, and billing reports Mostly read-only control plane. Current writes are limited to creating workspaces and variables; the published tools cannot trigger runs or approve applies. OAuth-based remote MCP was added March 24, 2026. No raw-state download or edit tool is listed.
Spacelift MCP GraphQL discovery and queries, Terraform/OpenTofu provider schemas from the OpenTofu Registry, Spacelift mutations, and direct Intent-managed resource lifecycle operations Read or write depending on OAuth scope. The write scope can change stacks, policies, runs, and Intent-managed infrastructure. The former /intent/mcp endpoint is scheduled for removal on August 1, 2026 in favor of /mcp.
env0 MCP server Projects, environments, deployment and approval actions, plan/apply logs, error analysis, drift and cloud inventory, and IaC generation from discovered resources Write-capable control plane. It can drive deployment actions, although the current repository explicitly blocks state:get. v1.1.0 was released May 27, 2026.
Harness IaCM MCP tools Workspace metadata, managed resource attributes and outputs, and private module registry entries Read-only, state-derived control-plane access. The documentation was last updated June 25, 2026 and lists no plan, apply, public-provider, or raw-state tools.

Two cautions follow from that table. First, "destructive operations disabled" does not always mean read-only. In the HashiCorp server, ENABLE_TF_OPERATIONS=false blocks several operations, but the documented create_run choices still include state refresh and a separately approved plan-and-apply flow. Review individual tools and token scopes, not only the server-level label.

Second, tools change faster than IaC conventions. HashiCorp's server moved from its first public release in May 2025 to v1.0 in June 2026. Spacelift is changing endpoints in August 2026. Pin a tested server or container version, inspect its advertised tools, and repeat the access review on upgrade. HashiCorp's own MCP security model recommends validating every write and warns about prompt injection, tool poisoning, rug pulls, and tool shadowing across multiple servers.

Why Does Context Become the Bottleneck?

An agent's context window is its working memory for the current inference. It includes system and project instructions, conversation history, retrieved file contents, tool definitions, tool calls and results, and the response being generated. Anthropic's context engineering article, published September 29, 2025, argues that adding more tokens eventually reduces recall and focus even when the content still fits.

IaC puts pressure on that window from both ends: the tools arrive before work starts, and the operational payloads arrive during the work.

Tool definitions can consume the session before the first prompt

An MCP tool definition includes a name, description, and JSON input schema. Traditional clients load all of those definitions at startup so the model knows what it can call. The cost depends much more on schema complexity than on the tool count. In Anthropic's November 24, 2025 advanced tool-use measurements, 35 GitHub tools occupied about 26,000 tokens, 11 Slack tools about 21,000, and a five-server setup with 58 tools about 55,000. Anthropic also reports seeing 134,000 tokens of definitions before optimization.

This behavior changed recently in Claude Code. Its current MCP documentation says tool search is on by default: tool names and server instructions load initially, then full definitions are discovered when needed. Anthropic reports an 85 percent reduction in a large example. The tradeoff is an extra discovery step on first use, and poorly named tools can be missed. For a small set of fewer than roughly ten tools, the Agent SDK guidance says loading them upfront is often faster.

Do not assume every agent has that protection. Claude Code falls back to upfront loading with some hosted model platforms and non-first-party API gateways unless tool search is explicitly supported, and not every model can use tool references. Check the context or tool panel at the start of a clean session.

Plan, state, schema, and log payloads can flood it during work

Terraform's JSON plan format can contain prior state, planned values, parsed configuration, resource changes with before/after values, drift, checks, and output changes. State includes resource identities and attributes. A provider schema covers every resource and data source in every provider used by the configuration, not only the resource being edited. A run log can repeat the same provider error hundreds of times.

This provider-schema cost is documented outside the AI context too. A HashiCorp support note updated January 21, 2026 says the provider protocol requests all schemas regardless of which resource types the configuration uses, and records past memory failures caused by large nested AWS schemas.

There is no defensible universal token count for a plan or state file. The total depends on resource count, attribute size, modules, provider behavior, and JSON formatting. A February 23, 2026 community/vendor sizing article reports state files around 3 MB for 200 AWS resources and 10 MB for 500, but it does not publish a reproducible method. Treat those figures as evidence that multi-megabyte state exists, not as a sizing formula.

For rough mental math, Anthropic's glossary estimates 3.5 English characters per token. Mostly ASCII JSON will vary, especially across model tokenizers, but the order of magnitude is useful:

Mostly ASCII payload Rough token count Operational meaning
35,000 characters, about 35 KB 10,000 Current Claude Code warning threshold for one MCP tool result
87,500 characters, about 88 KB 25,000 Current default Claude Code maximum for an MCP result whose server declares no tool-specific limit
1,000,000 characters, about 1 MB 286,000 A large share of many context windows before instructions, code, history, and output

The same arithmetic puts a 3 MB state near 857,000 tokens, before accounting for tokenizer variation. A plan that embeds prior state plus configuration and changes can be larger. For exact API work, use the token counting endpoint against the actual model; Anthropic notes that newer tokenizers can produce about 30 percent more tokens for the same content than earlier ones.

The lesson is not to buy the largest context window and paste everything into it. A payload can fit and still bury the resource address, replacement reason, or constraint that matters.

How Should You Manage Context During IaC Work?

The following practices combine documented agent features with an operational pattern for Terraform and OpenTofu. Exact commands such as /clear and /compact are Claude Code-specific; the principles apply to any client that can start a clean session, summarize history, load tools on demand, or run isolated workers.

Keep one task in one session

Start with a bounded outcome: "reconcile drift for workspace payments-prod" is a task; "clean up our Terraform" is not. Name the directory and workspace, say what may be changed, define the verification command, and state that apply is out of scope. If the investigation finds a module upgrade or an unrelated backend issue, record it for another session.

This is documented product guidance rather than folklore. The current Claude Code best practices say to clear context between unrelated tasks and start over after repeated failed corrections. The tradeoff is lost conversational detail, so decisions that must survive belong in a file.

Enable only the server and toolset the task needs

A module authoring session usually needs repository files, the CLI, and one registry source. It does not need billing, IAM, drift, or apply tools. A failed-run investigation may need read-only workspace and log tools, but it does not need workspace mutation. Use separate read and write OAuth scopes where the server offers them.

Tool search reduces token cost; it is not an authorization boundary. Disabling an unused server still reduces attack surface, name collisions, accidental calls, startup failures, and the chance that untrusted data reaches the model. The HashiCorp v1 server makes this concrete with --toolsets and --tools, so a client can expose only registry or even a short list such as provider search and details.

Load definitions and data just in time

Keep on-demand tool loading enabled for a large catalog. For data, retrieve the narrowest useful object: one provider resource page, one workspace, one run, or one resource change. Ask for IDs and counts before asking for detail. This introduces extra calls and latency, but it prevents a fleet-wide result from occupying the rest of the session.

Version context matters too. Read required_version, required_providers, and .terraform.lock.hcl before fetching documentation. "Latest AWS provider" is the wrong reference when the workspace is locked to an older version. HashiCorp's dependency lock documentation also notes that init -upgrade deliberately ignores prior provider selections, so an agent should not run it as routine setup.

Use a read-only subagent for noisy investigation

Plans, provider schemas, run logs, and large module trees are good subagent work. Give the worker a fresh context, read-only tools, the artifact path or run ID, and a strict return contract: affected addresses, action types, the first causal error, evidence locations, unresolved uncertainty, and no more than a page. Anthropic describes subagents consuming tens of thousands of tokens and returning a 1,000 to 2,000-token summary in its context engineering guidance.

Isolation is useful but lossy. A summary can omit the odd attribute that makes a replacement dangerous. Before changing or deleting infrastructure, the main agent and reviewer should inspect the filtered source slice, not trust the summary alone. Also verify tool inheritance: some clients give a subagent every MCP tool available to its parent unless you restrict it.

Plan, write the plan, then clear

For a large change, separate discovery from implementation. In the first session, keep the agent read-only and have it write a self-contained AGENT_PLAN.md containing:

  • the goal and explicit non-goals;
  • engine, version, backend, workspace, account, and region;
  • locked provider selections and exact module version constraints;
  • files and resource addresses expected to change;
  • invariants such as "no destroy" or "public endpoint must remain unchanged";
  • unresolved decisions and required approvals;
  • exact format, validation, test, and plan commands;
  • the evidence a reviewer must see before apply.

Review that file, clear the conversation, and begin implementation by pointing a clean session at it. Anthropic's current best-practices page recommends the same general pattern: write a self-contained specification, then execute it in a fresh session. The cost is a handoff boundary. A vague or stale plan transfers false confidence, so update it when reality changes.

Compact at a phase boundary, before the window is full

Use compaction when the same task needs continuity but earlier searches and tool results no longer deserve full fidelity. In Claude Code, /context shows where the window is going and /compact can take focus instructions such as "preserve modified files, workspace identity, invariants, test commands, and unresolved risks." /clear is better at a task boundary. These commands and their current behavior are listed in the Claude Code command reference.

Compaction is a summary, so it can erase a detail whose importance becomes clear later. Persist the task plan, decisions, modified-file list, and verification results first. Waiting until the window is nearly exhausted is also risky because the compaction request itself needs room.

Keep large outputs in protected files

Pass the agent a path and a query, not an entire payload. For example:

umask 077
ARTIFACT_DIR="$(mktemp -d "${TMPDIR:-/tmp}/iac-agent.XXXXXX")"
 
terraform plan -out="$ARTIFACT_DIR/plan.bin"
terraform show -json "$ARTIFACT_DIR/plan.bin" > "$ARTIFACT_DIR/plan.json"
 
jq '{
  format_version,
  terraform_version,
  applyable,
  complete,
  errored,
  resource_change_count: ((.resource_changes // []) | length),
  resource_drift_count: ((.resource_drift // []) | length),
  output_change_names: ((.output_changes // {}) | keys),
  check_count: ((.checks // []) | length),
  action_invocation_count: (
    ((.action_invocations // []) + (.deferred_action_invocations // [])) | length
  ),
  resource_changes: [
    (.resource_changes // [])[] |
    {address, previous_address, deposed, actions: .change.actions, action_reason}
  ]
}' "$ARTIFACT_DIR/plan.json" > "$ARTIFACT_DIR/change-index.json"

This index is for triage, not approval. If an apply is proposed, fail closed when the plan has an unsupported major format_version, is not applyable or complete, is errored, or contains an action invocation. Terraform actions can invoke systems such as Ansible or Lambda without a resource-state change, so an index of resource_changes alone can miss them. The reviewer must inspect the full final human-readable plan, plus relevant checks, drift, outputs, and source slices. HashiCorp documents both the JSON compatibility rules and action invocation behavior.

Ask the agent to read change-index.json, then query only the before, after, and after_unknown fields for addresses that need review. The raw plan remains available without sitting in every turn. OpenTofu 1.12 added -json-into=FILENAME for writing machine-readable command output to a file while keeping human output on screen, another useful form of this pattern (released May 14, 2026).

Files create a security tradeoff. Plan and state JSON can hold plaintext secrets, and agent transcripts or spilled tool results may also be plaintext. Use a restricted temporary directory or approved encrypted artifact store, keep it outside Git, set a retention period, and clean it up. Do not turn plan.json into a convenient permanent knowledge file.

What Safe Defaults Should an IaC Agent Use?

This checklist is synthesized operational guidance. The underlying plan, state, locking, and product behaviors are documented; the exact permission policy is something each team must own.

  • Start with read-only cloud and control-plane credentials plus a least-privilege, plan-capable backend identity. Planning may need state read and lock acquire/release permissions; deny state writes where the backend can separate them. Do not work around a lock failure with -lock=false.
  • Deny apply, destroy, Terraform action invocations, state writes, force-unlock, -lock=false, and -auto-approve by default. Do not use -refresh=false or routine -target to make a plan smaller; HashiCorp warns that both can hide an incomplete view.
  • Treat plan as code execution when the repository or dependencies are not trusted. Review provider lockfile and module-source changes, use a sandbox, and restrict credentials and outbound network access.
  • Pin the Terraform or OpenTofu version, provider selections, exact module versions, and MCP server version. Do not let the agent run init -upgrade unless an upgrade is the task.
  • Before planning, print and verify the engine, working directory, backend, workspace, account or subscription, region, and variable source. Put these values in the review summary.
  • Keep raw state, saved plans, JSON plans, and logs out of Git and out of the conversation. Return filtered addresses and actions, with a path back to the protected source.
  • Run fmt, validate, policy checks, and a speculative plan before asking for approval. Run only verified plan-only or safely mocked tests under the no-apply policy; apply-mode tests need separate authorization and a disposable account. Flag every delete, replacement, action invocation, failed check, and output change separately.
  • Keep apply in a human-approved pipeline by default. Bind approval to the SHA-256 digest of a saved plan held in immutable storage, or to a remote run ID, together with the commit, workspace, variable set, and provider lockfile. Verify that binding at apply time and remove the agent's write access before approval. If the agent is exceptionally authorized to apply, add a time limit, state locking, audit logs, and a person watching the run.
  • Treat MCP tool output and registry content as untrusted input. Review tool-list changes after upgrades and avoid connecting unrelated servers in the same privileged session.

What Do Good AI-Assisted IaC Workflows Look Like?

Each example below uses a fresh session and stops at a reviewable handoff. The prompts are tool-agnostic; replace identifiers and commands for your environment.

Drift reconciliation

Connect the repository, a registry source for the locked provider version, and a read-only control-plane server that can inspect drift for one workspace. Do not begin with a fleet-wide state or plan dump.

Goal: reconcile drift in workspace payments-prod only.
Allowed: read workspace metadata, drift, the last successful run, and the
specific plan/log slices needed for changed addresses; edit HCL; run checks
and a speculative plan.
Forbidden: apply, refresh-only apply, state writes, force-unlock, and changes
outside modules/payments.
First return: workspace/account/region/version confirmation, changed resource
addresses, and for each address whether the remote change appears intentional,
unwanted, or unresolved. Keep raw output in a protected file.

Use a read-only subagent to classify the noisy drift result. Then make the human decision: codify an intentional remote change in HCL, or let a normal reviewed plan revert an unwanted change. A -refresh-only plan is useful for inspection, but applying it accepts remote changes into state without changing the remote objects. HashiCorp's drift tutorial warns that configuration must also be updated when the drift is intentional, or a later normal apply can undo it.

The final handoff is a code diff plus a normal plan limited by workspace scope, not by routine -target. A reviewer inspects all deletes, replacements, and sensitive boundaries.

Module refactor

Start without a state-aware MCP server. The discovery session needs the repository, registry documentation for locked versions, and local validation commands. Ask it to map old and new resource addresses, module call sites, version constraints, representative workspaces, and every test file into AGENT_PLAN.md, then clear. Before authorizing terraform test or tofu test, inspect each run block and provider: the commands can create real infrastructure and cleanup can fail.

Implement the reviewed module refactor in AGENT_PLAN.md.
Preserve every resource identity with moved blocks where supported. Do not run
state mv or change provider selections. Run fmt and validate. Run only tests
explicitly authorized in AGENT_PLAN.md as plan-only or safely mocked; stop
before any apply-mode test.
Plan the listed workspaces one at a time, write each raw plan outside Git, and
return only action counts plus any delete or replacement address.
Stop if a workspace cannot produce a no-destroy plan.

Terraform's moved block records address changes in configuration, which is easier to review and repeat than asking an agent to mutate each workspace's state by hand. The tradeoff is version compatibility and coverage: one clean workspace plan does not prove every caller uses the module the same way. Keep each workspace plan in its own narrow context or subagent and bring back a small matrix of results.

Failed-run triage

Use a read-only control-plane connection scoped to one failed run. Ask for run metadata first, then the relevant plan or apply log. A subagent can read the full log and return the first causal error, affected resource address, provider or API operation, evidence offsets, and whether the run completed any changes before failing.

Triage run run-abc123 in workspace orders-prod.
Read only. Put the complete log in a protected temporary file. Return the first
causal error rather than repeated downstream errors, the affected resource
address, the exact provider version, and up to 30 surrounding lines with
secrets redacted. If this was an apply failure, identify completed actions from
the run record. Do not retry or create a new run.

The main session verifies the exact provider documentation, edits the smallest relevant code surface, and produces a new speculative plan. If the apply was partial, refresh and replan through the normal workflow instead of assuming rollback. Credential and permission errors should end with a request to the credential owner, not a prompt asking the model to reveal or invent a secret.

New-workspace provisioning

This workflow genuinely needs a control-plane write, but not at the start. Use a read-only session to write a workspace manifest containing the project or environment, workspace name, eventual VCS repository and path, Terraform or OpenTofu version, execution mode, variable names and sensitivity, policy sets, tags, drift settings, and both automatic run-queue and auto-apply settings. Review the manifest before enabling the create tool.

Create exactly the base workspace described in WORKSPACE.md, detached from VCS.
You may create the workspace and non-secret variables only. Do not upload secret
values, attach VCS, trigger a run, approve an apply, or modify an existing
workspace. Read the workspace back and diff it against WORKSPACE.md. Stop on any
mismatch. If this platform cannot create it detached, or cannot atomically
disable automatic run queueing and auto-apply, stop before creation.

Only after read-back confirms that automatic queueing and auto-apply are disabled should a separate approved step attach the reviewed VCS path. Provide secrets through the platform's approved secret path or identity integration rather than the conversation. After creation and attachment, drop the write scope. In a new read-only session, initialize the repository and request a speculative plan. Workspace creation is a control-plane change even when no cloud resource has been created, and attaching VCS too early can enqueue a run before the agent can verify the safeguards.

Where Should You Start?

Begin with a non-production module and a registry-only MCP server. Give the agent a single change, locked versions, no write credentials, and permission to stop after authorized checks and a speculative plan. Watch what it reads, how much context the tools consume, and whether its plan summary points back to exact resource addresses and source artifacts.

Add read-only run or drift access when that loop is predictable. Add control-plane writes last, one tool and one task at a time. The goal is not maximum agent reach. It is a short, inspectable path from intent to a plan a human can trust.

Frequently asked questions

Can an AI coding agent safely run terraform apply or tofu apply?

It can run the command if its tools and credentials permit it, but the safer default is that it cannot. Let the agent edit configuration, run checks, and produce a saved or remote plan. A human or a controlled delivery pipeline should review the final plan and perform the apply.

What is the difference between a registry-only and a state-touching MCP server?

A registry-only server returns provider, resource, data-source, and module documentation. A state-aware or control-plane server can read workspace data, runs, plans, outputs, variables, drift, or resource inventory. A write-capable server may also create runs, approve applies, or manage infrastructure, so its token and OAuth scopes are part of the infrastructure security boundary.

How should an AI agent read a large Terraform plan?

Save the raw plan and JSON representation to a protected, ignored path, then have the agent query only the change summary, affected resource addresses, deletions, replacements, and relevant attributes. Do not paste the entire JSON document into the conversation.

Does MCP tool search solve the IaC context problem?

It solves the upfront tool-definition part when the client supports on-demand loading, but it does not shrink plan logs, state JSON, provider schemas, or conversation history. It also adds a discovery step and is not available in every model, client, or gateway.
About the author
Ryan Feedirector of platform engineering at Scalr
Ryan Fee is the director of platform engineering at Scalr, with over 15 years of experience improving infrastructure experiences at companies large and small.