website/docs/language/resources/behavior.mdx
A resource block declares that you want a particular infrastructure object
to exist with the given settings. If you are writing a new configuration for
the first time, the resources it defines will exist only in the configuration,
and will not yet represent real infrastructure objects in the target platform.
Applying an OpenTofu configuration is the process of creating, updating, and destroying real infrastructure objects in order to make their settings match the configuration.
When OpenTofu creates a new infrastructure object represented by a resource
block, the identifier for that real object is saved in OpenTofu's
state, allowing it to be updated and destroyed
in response to future changes. For resource blocks that already have an
associated infrastructure object in the state, OpenTofu compares the
actual configuration of the object with the arguments given in the
configuration and, if necessary, updates the object to match the configuration.
In summary, applying an OpenTofu configuration will:
removed block within the configuration.This general behavior applies for all resources, regardless of type. The details of what it means to create, update, or destroy a resource are different for each resource type, but this standard set of verbs is common across them all.
The meta-arguments within resource blocks, documented in the
sections below, allow some details of this standard resource behavior to be
customized on a per-resource basis.
Expressions within an OpenTofu module can access
information about resources in the same module, and you can use that information
to help configure other resources. Use the <RESOURCE TYPE>.<NAME>.<ATTRIBUTE>
syntax to reference a resource attribute in an expression.
In addition to arguments specified in the configuration, resources often provide read-only attributes with information obtained from the remote API; this often includes things that can't be known until the resource is created, like the resource's unique random ID.
Many providers also include data sources, which are a special type of resource used only for looking up information.
For a list of the attributes a resource or data source type provides, consult its documentation; these are generally included in a second list below its list of configurable arguments.
For more information about referencing resource attributes in expressions, see Expressions: References to Resource Attributes.
Most resources in a configuration don't have any particular relationship, and OpenTofu can make changes to several unrelated resources in parallel.
However, some resources must be processed after other specific resources; sometimes this is because of how the resource works, and sometimes the resource's configuration just requires information generated by another resource.
Most resource dependencies are handled automatically. OpenTofu analyses any
expressions within a resource block to find references
to other objects, and treats those references as implicit ordering requirements
when creating, updating, or destroying resources. Since most resources with
behavioral dependencies on other resources also refer to those resources' data,
it's usually not necessary to manually specify dependencies between resources.
However, some dependencies cannot be recognized implicitly in configuration. For
example, if OpenTofu must manage access control policies and take actions
that require those policies to be present, there is a hidden dependency between
the access policy and a resource whose creation depends on it. In these rare
cases,
the depends_on meta-argument
can explicitly specify a dependency.
You can also use the replace_triggered_by lifecycle argument to add dependencies between otherwise independent resources. It forces OpenTofu to replace the parent resource when there is a change to a referenced resource or resource attribute.
A lifecycle block inside a resource block allows some customization of
OpenTofu's behavior relating to instances of a resource at different phases
of its lifecycle.
resource "example" "example" {
# ...normal resource arguments...
lifecycle {
# ...lifecycle arguments...
}
}
The following arguments and nested block types are supported in the lifecycle
block for a managed resource:
create_before_destroy (bool) - By default, when OpenTofu must change
a resource argument that cannot be updated in-place due to
remote API limitations, OpenTofu will instead destroy the existing object
and then create a new replacement object with the new configured arguments.
The create_before_destroy meta-argument changes this behavior so that
the new replacement object is created first, and the prior object
is destroyed after the replacement is created.
This is an opt-in behavior because many remote object types have unique
name requirements or other constraints that must be accommodated for
both a new and an old object to exist concurrently. Some resource types
offer special options to append a random suffix onto each object name to
avoid collisions, for example. OpenTofu CLI cannot automatically activate
such features, so you must understand the constraints for each resource
type before using create_before_destroy with it.
Note that OpenTofu propagates and applies the create_before_destroy meta-attribute
behaviour to all resource dependencies. For example, if create_before_destroy
is enabled on resource A but not on resource B, but resource A is dependent on
resource B, then OpenTofu enables create_before_destroy for resource B
implicitly by default and stores it in state snapshots. You cannot override
create_before_destroy to false on resource B because that would cause
dependency cycles in the graph.
Destroy provisioners of this resource do not run during replacement if
create_before_destroy is set to true. GitHub issue #13549 contains more details.
enabled (bool) - Controls whether a resource is created and managed by OpenTofu.
When set to false, the resource is excluded from the configuration as if it didn't exist,
and any existing infrastructure object will be destroyed. When set to true (the default),
the resource operates normally.
For more information, refer to the enabled meta-argument.
prevent_destroy (bool) - This meta-argument, when set to true, will
cause OpenTofu to reject with an error any plan that would destroy the
infrastructure object associated with the resource, as long as the argument
remains present in the configuration.
This can be used as a measure of safety against the accidental replacement
of objects that may be costly to reproduce, such as database instances.
However, it will make certain configuration changes impossible to apply,
and will prevent the use of the tofu destroy command once such
objects are created, and so this option should be used sparingly.
Since this argument must be present in configuration for the protection to
be active, this setting cannot prevent the remote object from being destroyed
when the resource block is removed from configuration entirely: in that
case, the prevent_destroy setting is removed along with it, and so OpenTofu
would allow the destroy operation to succeed.
In case you want to retain the infrastructure object even after removing the
resource block from configuration, consider using the destroy argument
documented below instead. Note that, if you set destroy = false, OpenTofu will
change the destroy actions to a variant of forget action, and prevent_destroy
will not have any effect.
destroy (bool) - By default, when a resource is removed from the configuration,
requires replacement, or is explicitly destroyed using the tofu destroy command,
OpenTofu will destroy the corresponding infrastructure object. Setting this
meta-argument to false changes this behavior so that OpenTofu will instead
"forget" the resource instance, removing it from the state without destroying the actual
infrastructure object.
:::note
lifecycle.destroy only accepts constant boolean values (true or false).
:::
When a resource with destroy = false is removed from the configuration or requires replacement,
OpenTofu will plan to forget it rather than destroy it. The resource will
be removed from the state file, but the actual infrastructure object will
remain unchanged in your cloud provider or other remote system. If the resource requires replacement,
OpenTofu will then create a new resource instance as per the current configuration.
This is useful when you want to keep the resource in configuration but alter its destruction behavior. Incomplete list of use cases includes:
Note that this argument is persisted in the state, once you set and apply destroy = false for a resource
OpenTofu will not plan the resource destruction unless you explicitly change it back to true or remove the option from the corresponding resource configuration block.
OpenTofu errs on the side of caution and avoids destroying resources that were marked with destroy = false in the last applied configuration for the resource instance.
If you are using single instance resources (no count or for_each), you can override this attribute in the state by writing explicit removed block for the resource instance with destroy = true option.
:::note
This argument can also be used in removed blocks
to control whether resources should be destroyed or forgotten when explicitly
removing them from OpenTofu management. The behavior is identical in both contexts.
Generally, prefer to use removed blocks when you want to remove resources from your configurations as a method of refactoring.
Use destroy lifecycle argument when you want to control the destruction behavior of resources that are still present in your configuration.
:::
The destroy argument also applies when using the tofu destroy command.
Resources with destroy = false will be forgotten rather than destroyed,
and the command will exit with a non-zero status code to indicate that some
resources were not fully removed. See the tofu destroy command documentation
for more details.
:::warning Once a resource is forgotten (removed from state), OpenTofu will no longer track it. If you later add the resource back to your configuration with the same address, OpenTofu will attempt to create a new resource, which may fail if the infrastructure object still exists. You may need to import the existing resource or use a different resource address. :::
<span id="ignore_changes">ignore_changes</span> (list of attribute names) - By default, OpenTofu detects
any difference in the current settings of a real infrastructure object
and plans to update the remote object to match configuration.
The ignore_changes feature is intended to be used when a resource is
created with references to data that may change in the future, but should
not affect said resource after its creation. In some rare cases, settings
of a remote object are modified by processes outside of OpenTofu, which
OpenTofu would then attempt to "fix" on the next run. In order to make
OpenTofu share management responsibilities of a single object with a
separate process, the ignore_changes meta-argument specifies resource
attributes that OpenTofu should ignore when planning updates to the
associated remote object.
The arguments corresponding to the given attribute names are considered
when planning a create operation, but are ignored when planning an
update. The arguments are the relative address of the attributes in the
resource. Map and list elements can be referenced using index notation,
like tags["Name"] and list[0] respectively.
resource "aws_instance" "example" {
# ...
lifecycle {
ignore_changes = [
# Ignore changes to tags, e.g. because a management agent
# updates these based on some ruleset managed elsewhere.
tags,
]
}
}
Use the special keyword all instead of an attribute list to instruct
OpenTofu to ignore changes to all attributes, which means that OpenTofu can
create and destroy the remote object but will never propose updates to it.
Only attributes defined by the resource type can be ignored.
ignore_changes cannot be applied to itself or to any other meta-arguments.
precondition and postcondition blocks, as described in
Custom Conditions.
<span id="replace_triggered_by">replace_triggered_by</span> (list of resource or attribute references) -
Replaces the resource when any of the referenced
items change. Write a list of expressions referencing managed resources,
resource instances, or instance attributes. When used in a resource that
uses count or for_each, you can use count.index or each.key in the
expression to refer to specific instances of other resources that are
configured with the same count or collection.
References trigger replacement in the following conditions:
You can only refer to managed resources in replace_triggered_by
expressions. This lets you modify these expressions without forcing
replacement.
resource "aws_appautoscaling_target" "ecs_target" {
# ...
lifecycle {
replace_triggered_by = [
# Replace `aws_appautoscaling_target` each time this instance of
# the `aws_ecs_service` is replaced.
aws_ecs_service.svc.id
]
}
}
replace_triggered_by allows only resource addresses because the decision is
based on the planned actions for all of the given resources. Plain values such
as local values or input variables do not have planned actions of their own,
but you can treat them with a resource-like lifecycle by using them with
the terraform_data resource type.
While most resource types correspond to an infrastructure object type that is managed via a remote network API, there are certain specialized resource types that operate only within OpenTofu itself, calculating some results and saving those results in the state for future use.
For example, local-only resource types exist for generating private keys, issuing self-signed TLS certificates, and even generating random ids. While these resource types often have a more marginal purpose than those managing "real" infrastructure objects, they can be useful as glue to help connect together other resources.
The behavior of local-only resources is the same as all other resources, but their result data exists only within the OpenTofu state. "Destroying" such a resource means only to remove it from the state, discarding its data.