Files
opentf/website/docs/language/data-sources/index.mdx
Martin Atkins dc9bec611c website: Reorganize and tidy some lifecycle-related information
Over time the discussion about "lifecycle" blocks in the documentation
became confusing because the docs originally written for managed resource
lifecycle got partially generalized for resources of other modes and for
module calls, even though each of those has a completely different
lifecycle and thus a different set of lifecycle settings.

This is a first pass at trying to reorganize that so that the "lifecycle"
page is really just an index of all of the different kinds of lifecycle
block that exist in the language, while the main documentation for each
use of that block type now belongs with the documentation of the block
it's nested within.

While working on this I also found that there was some duplication inside
the "data sources" page where the same information was described multiple
times, and a few other cases where things had become inconsistent over
time. This also includes a little extra content to try to clarify the
difference between managed, data, and ephemeral resources and to make it
explicit that the "Resources" section is focused only on managed resources
because that is the primary resource mode.

As usual there's lots more that could be done here -- this documentation
has gradually evolved over time and is full of weird quirks due to that
evolution -- but I decided to draw a line here so that the diff wouldn't
get too large.

Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2025-10-17 15:08:14 -07:00

208 lines
8.8 KiB
Plaintext

---
description: >-
Data sources allow OpenTofu to use external data, function output, and data
from other configurations. Learn data resource arguments, behavior, and
lifecycle.
---
# Data Sources
_Data sources_ allow OpenTofu to use information defined outside of OpenTofu,
defined by another separate OpenTofu configuration, or modified by functions.
Each [provider](../../language/providers/index.mdx) may offer data sources
alongside its set of [resource](../../language/resources/index.mdx)
types.
## Using Data Sources
A data source is accessed via a special kind of resource known as a
_data resource_, declared using a `data` block:
```hcl
data "aws_ami" "example" {
most_recent = true
owners = ["self"]
tags = {
Name = "app-server"
Tested = "true"
}
}
```
A `data` block requests that OpenTofu read from a given data source ("aws_ami")
and export the result under the given local name ("example"). The name is used
to refer to this resource from elsewhere in the same OpenTofu module, but has
no significance outside of the scope of a module.
The data source and name together serve as an identifier for a given
resource and so must be unique within a module.
Within the block body (between `{` and `}`) are query constraints defined by
the data source. Most arguments in this section depend on the
data source, and indeed in this example `most_recent`, `owners` and `tags` are
all arguments defined specifically for [the `aws_ami` data source](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami).
When distinguishing from data resources, the primary kind of resource (as declared
by a `resource` block) is known as a _managed resource_. Both kinds of resources
take arguments and export attributes for use in configuration, but while
managed resources cause OpenTofu to create, update, and delete infrastructure
objects, data resources cause OpenTofu only to _read_ objects. For brevity,
managed resources are often referred to just as "resources" when the meaning
is clear from context.
## Data Source Arguments
Each data resource is associated with a single data source, which determines
the kind of object (or objects) it reads and what query constraint arguments
are available.
Each data source in turn belongs to a [provider](../../language/providers/index.mdx),
which is a plugin for OpenTofu that offers a collection of resource types and
data sources that most often belong to a single cloud or on-premises
infrastructure platform.
Most of the items within the body of a `data` block are defined by and
specific to the selected data source, and these arguments can make full
use of [expressions](../../language/expressions/index.mdx) and other dynamic
OpenTofu language features.
However, there are some [meta-arguments](#meta-arguments) that are defined by
OpenTofu itself and apply across all data resource types. These arguments often
have additional restrictions on what language features can be used with them,
and are described in more detail in the following sections.
## Data Resource Behavior
OpenTofu reads data resources during the planning phase when possible, but
announces in the plan when it must defer reading resources until the apply
phase to preserve the order of operations. OpenTofu defers reading data
resources in the following situations:
* At least one of the given arguments is a managed resource attribute or
other value that OpenTofu cannot predict until the apply step.
* The data resource depends directly on a managed resource that itself has
planned changes in the current plan.
* The data resource has
[custom conditions](#custom-condition-checks)
and it depends directly or indirectly on a managed resource that itself
has planned changes in the current plan.
Refer to [Data Resource Dependencies](#data-resource-dependencies) for details
on what it means for a data resource to depend on other objects. Any resulting
attribute of such a data resource will be unknown during planning, so it cannot
be used in situations where values must be fully known.
## Meta-Arguments
The OpenTofu language defines several meta-arguments, which can be used with
any data resource type to change the behavior of resources.
The following meta-arguments are documented on separate pages:
- [`depends_on`, for specifying hidden dependencies](../../language/meta-arguments/depends_on.mdx)
- [`enabled`, for creating conditionally single-resource instances according to a expression](../../language/meta-arguments/enabled.mdx)
- [`count`, for creating multiple resource instances according to a count](../../language/meta-arguments/count.mdx)
- [`for_each`, to create multiple instances according to a map, or set of strings](../../language/meta-arguments/for_each.mdx)
- [`provider`, for selecting a non-default provider configuration](../../language/meta-arguments/resource-provider.mdx)
- [`lifecycle`, for lifecycle customizations](#lifecycle-customizations)
## Lifecycle Customizations
A `lifecycle` block inside a `data` block allows some customization of
OpenTofu's behavior relating to instances of a resource at different phases
of its lifecycle.
```hcl
data "example" "example" {
# ...normal resource arguments...
lifecycle {
# ...lifecycle arguments...
}
}
```
The following arguments and nested block types are supported in the `lifecycle`
block for a data resource:
* `enabled` (bool) - Controls whether the data resource will be read by OpenTofu.
When set to `false`, the resource is excluded from the configuration as if it
didn't exist. When set to `true` (the default), the resource operates normally.
For more information, refer to [the `enabled` meta-argument](../../language/meta-arguments/enabled.mdx).
* `precondition` and `postcondition` blocks, as described in
[Custom Conditions](../../language/expressions/custom-conditions.mdx#preconditions-and-postconditions).
## Local-only Data Sources
While many data sources correspond to an infrastructure object type that
is accessed via a remote network API, some specialized data sources operate
only within OpenTofu itself, calculating some results and exposing them
for use elsewhere.
For example, local-only data sources exist for
[rendering templates](https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/file),
[reading local files](https://registry.terraform.io/providers/hashicorp/local/latest/docs/data-sources/file), and
[rendering AWS IAM policies](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document).
The behavior of local-only data sources is the same as all other data
sources, but their result data exists only temporarily during an OpenTofu
operation, and is re-calculated each time a new plan is created.
## Data Resource Dependencies
Data resources have the same dependency resolution behavior
[as defined for managed resources](../../language/resources/behavior.mdx#resource-dependencies).
Setting the `depends_on` meta-argument within `data` blocks defers reading of
the data source until after all changes to the dependencies have been applied.
In order to ensure that data sources are accessing the most up to date
information possible in a wide variety of use cases, arguments directly
referencing managed resources are treated the same as if the resource was
listed in `depends_on`. This behavior can be avoided when desired by indirectly
referencing the managed resource values through a `local` value, unless the
data resource itself has
[custom conditions](#custom-condition-checks).
## Custom Condition Checks
You can use `precondition` and `postcondition` blocks to specify assumptions and guarantees about how the data source operates. The following examples creates a postcondition that checks whether the AMI has the correct tags.
``` hcl
data "aws_ami" "example" {
id = var.aws_ami_id
lifecycle {
# The AMI ID must refer to an existing AMI that has the tag "nomad-server".
postcondition {
condition = self.tags["Component"] == "nomad-server"
error_message = "tags[\"Component\"] must be \"nomad-server\"."
}
}
}
```
Custom conditions can help capture assumptions, helping future maintainers understand the configuration design and intent. They also return useful information about errors earlier and in context, helping consumers more easily diagnose issues in their configurations.
Refer to [Custom Condition Checks](../../language/expressions/custom-conditions.mdx#preconditions-and-postconditions) for more details.
### Non-Default Provider Configurations
Similarly to [resources](../../language/resources/index.mdx), when
a module has multiple configurations for the same provider you can specify which
configuration to use with the `provider` meta-argument:
```hcl
data "aws_ami" "web" {
provider = aws.west
# ...
}
```
See
[The Resource `provider` Meta-Argument](../../language/meta-arguments/resource-provider.mdx)
for more information.