Cross-state reads, without the whole state: Solving Terraform remote state
It often looks like the default way to share output values between separate Terraform configurations, but terraform_remote_state pulls the entirety of every output from every state file, even when you only require a single field, creating significant security and performance overhead. Stategraph eliminates this inefficiency by reading only the specific data your module consumes, ensuring the rest of your state remains isolated and secure.
terraform_remote_state always fetches the full state, regardless of what you reference
Scaling Terraform for teams that manage infrastructure across multiple domains requires decoupling root modules, whether teams are split by service, account, region, or Terraform workspace. However, establishing inter-state dependencies often leads to suboptimal patterns. The default reflex is the terraform_remote_state, one of the remote state data sources teams reach for when separate configurations need to share outputs, but it lacks granularity.
On every plan, it reads the full remote state snapshot to expose root module outputs, even when your terraform configuration needs only a single VPC ID.
You might only need a single VPC ID to create downstream cloud resources, but you're forced to inherit the entire blast radius of the network team's state, introducing unnecessary security risks and performance drag.
What is remote state in Terraform? The practical answer is that remote state lets one Terraform configuration read output values from another configuration's state file, often through a remote backend such as S3, HCP Terraform, or Terraform Cloud.
The terraform_remote_state tax
This is the standard, yet flawed, workflow for any Terraform architecture with multiple separate states. The network team maintains root module A, exposing remote state outputs such as vpc_id, private_subnet_ids, public_subnet_ids, nat_gateway_ips, peering_connection_ids, and dozens more. Meanwhile, the application team managing root module B requires only a single field from that entire collection.
In this scenario, Module B establishes a dependency on a single attribute from the networking state, with the backend configuration pointing at the producer's state file.
The appearance of simplicity is deceptive. During a terraform plan, this data source fetches the entirety of the remote state file at network/terraform.tfstate. The consumer code may refer to one attribute, but the access model still centers on the full snapshot rather than the specific field.
This architectural pattern introduces security, performance, and coupling liabilities.
Security
In a production environment, values marked as sensitive are still transmitted in the wire payload, alongside any outputs that should have been protected but weren't. Every consumer inherits the producer's complete output surface area indefinitely, because remote state access is granted at the state snapshot boundary rather than the field boundary. Producers lack visibility into who is consuming their data, while consumers are forced to ingest information they never requested.
Performance
Processing a 2 MB state file with hundreds of outputs incurs the same network and parsing overhead on every plan, including when referencing a single attribute. Scaled across every consumer and every CI run, multi-state architectures pay this performance tax in perpetuity, even when state locking protects concurrent writes and the actual read only needs one field.
Coupling
From the producer's perspective, it is impossible to determine which fields are truly load-bearing. Renaming an output becomes a guessing game; removing one is a leap of faith into potential breaking changes.
The ideal contract
The desired interaction should mirror a database query. A SELECT vpc_id FROM network.outputs operation returns exactly one column. It doesn't stream every row of every table simply because you performed a JOIN on the schema. You request one field; you receive one field.
Cross-state references should follow this logic. If a producer state contains fifty outputs and a consumer references only one, only that single value should travel. The remaining forty-nine should remain isolated, allowing the producer to add, remove, or rotate them without impacting the consumer team.
If you reference a single field, you should ingest exactly one field. This is the baseline expectation for every modern database engine and RPC system. In the Terraform state model, however, it remains the exception — until now.
Precision access is how Stategraph resolves outputs
Stategraph preserves your existing HCL logic without modification. You use the same terraform_remote_state data source and the same .outputs.field_name accessors, requiring zero module refactoring. The transformation occurs exclusively during the execution of the plan.
When the engine encounters a cross-state dependency, it targets only the specific attribute path defined in your configuration. If you reference data.terraform_remote_state.network.outputs.vpc_id, Stategraph extracts only the vpc_id from the source state. Whether you require one field or five, the engine retrieves exactly what is consumed. Every other output, and the sensitive data they may hold, remains securely isolated within the producer's state file.
Same workflow. Same accessor syntax. Same semantics from the consumer's point of view, the field arrives, the resource gets configured, the plan succeeds. The difference is what didn't move. The producer's other outputs were not serialized into the plan, were not transferred over the wire, and were not parsed in the consumer's process. They stayed where they belong.
A remote state shouldn't be an attack surface for every consumer. The producer of a state is the right place to decide what is shared. The consumer is the right place to decide what is needed. The transport between them shouldn't be "everything, every time."
The impact of precision access
Scoped security. Sensitive values remain isolated within their home state. If the network team's state exposes peering credentials as an output, application consumers won't ingest that data unless they explicitly reference it. Field-level granularity replaces the dangerous "all-or-nothing" state file exposure.
Performance at scale. Consumer plans are no longer penalized by the growth of producer modules. Expanding a network state to 500 outputs incurs zero additional cost for modules that don't reference them. The performance cliff typical of massive multi-state architectures is effectively eliminated.
Granular auditability. Stategraph provides the visibility security teams have demanded since terraform_remote_state first shipped. Instead of logging a broad "read" of the entire network state, the engine records the exact output fields each plan accessed.
Refactoring without risk. Producers gain the freedom to evolve their HCL without fear of invisible breakage. Because Stategraph tracks exactly which outputs are load-bearing for each consumer, removing or renaming unreferenced fields is no longer a leap of faith.
The shape of the solution
Tools like Terragrunt and the terraform_remote_state data source were engineered as workarounds for a fundamental limitation: the systems we use to store Terraform state still treat the state file as a coarse unit of storage.
The Terraform state file is a coarse unit of storage. Historically, even when teams moved to a remote backend to store state, they were still forced to retrieve the entire payload or nothing at all.
By treating state as a queryable graph rather than a flat file, we resolve this structural inefficiency. When storage is indexed at the field level, reads occur at the field level. This isn't just a smarter wrapper around terraform_remote_state; it is a fundamentally smarter read path.
Cross-state references should mirror the logic of a database query rather than a bulk file download. The producer maintains data isolation, while the consumer receives exactly the requested field. No other information moves.
If you reference a single field, you should ingest exactly one field. Standard multi-state architectures frequently suffer from secret sprawl and inefficient payloads. Stategraph resolves this by retrieving cross-state outputs at the field level, preserving your existing HCL while drastically reducing your blast radius.