mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-21 10:47:34 -05:00
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>
260 lines
11 KiB
Plaintext
260 lines
11 KiB
Plaintext
---
|
|
description: >-
|
|
Resources correspond to infrastructure objects like virtual networks or
|
|
compute instances. Learn about resource types, syntax, behavior, and
|
|
arguments.
|
|
---
|
|
|
|
# Resource Blocks
|
|
|
|
_Resources_ are the most important element in the OpenTofu language.
|
|
Each resource block describes one or more infrastructure objects, such
|
|
as virtual networks, compute instances, or higher-level components such
|
|
as DNS records.
|
|
|
|
## Resource Syntax
|
|
|
|
Resource declarations can include a number of advanced features, but only
|
|
a small subset are required for initial use. More advanced syntax features,
|
|
such as single resource declarations that produce multiple similar remote
|
|
objects, are described later in this page.
|
|
|
|
```hcl
|
|
resource "aws_instance" "web" {
|
|
ami = "ami-a1b2c3d4"
|
|
instance_type = "t2.micro"
|
|
}
|
|
```
|
|
|
|
A `resource` block declares a resource of a given type ("aws_instance")
|
|
with a given local name ("web"). The name is used to refer to this resource
|
|
from elsewhere in the same module, but has no significance outside
|
|
that module's scope.
|
|
|
|
The resource type 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 the configuration arguments
|
|
for the resource itself. Most arguments in this section depend on the
|
|
resource type, and indeed in this example both `ami` and `instance_type` are
|
|
arguments defined specifically for [the `aws_instance` resource type](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance).
|
|
|
|
:::note
|
|
Resource names must start with a letter or underscore, and may
|
|
contain only letters, digits, underscores, and dashes.
|
|
:::
|
|
|
|
## Resource Types
|
|
|
|
Each resource is associated with a single _resource type_, which determines
|
|
the kind of infrastructure object it manages and what arguments and other
|
|
attributes the resource supports.
|
|
|
|
### Providers
|
|
|
|
Each resource type is implemented by a [provider](../../language/providers/requirements.mdx),
|
|
which is a plugin for OpenTofu that offers a collection of resource types. A
|
|
provider usually provides resources to manage a single cloud or on-premises
|
|
infrastructure platform. Providers are distributed separately from OpenTofu
|
|
itself, but OpenTofu can automatically install most providers when initializing
|
|
a working directory.
|
|
|
|
In order to manage resources, a module must specify which providers it
|
|
requires. Additionally, most providers need some configuration in order to
|
|
access their remote APIs, and the root module must provide that configuration.
|
|
|
|
For more information, see:
|
|
|
|
- [Provider Requirements](../../language/providers/requirements.mdx), for declaring which
|
|
providers a module uses.
|
|
- [Provider Configuration](../../language/providers/configuration.mdx), for configuring provider settings.
|
|
|
|
OpenTofu usually automatically determines which provider to use based on a
|
|
resource type's name. (By convention, resource type names start with their
|
|
provider's preferred local name.) When using multiple configurations of a
|
|
provider (or non-preferred local provider names), you must use the `provider`
|
|
meta-argument to manually choose an alternate provider configuration. See
|
|
[the `provider` meta-argument](../../language/meta-arguments/resource-provider.mdx) for more details.
|
|
|
|
### Resource Arguments
|
|
|
|
Most of the arguments within the body of a `resource` block are specific to the
|
|
selected resource type. The resource type's documentation lists which arguments
|
|
are available and how their values should be formatted.
|
|
|
|
The values for resource arguments can make full use of
|
|
[expressions](../../language/expressions/index.mdx) and other dynamic OpenTofu
|
|
language features.
|
|
|
|
There are also some _meta-arguments_ that are defined by OpenTofu itself
|
|
and apply across all resource types. (See [Meta-Arguments](#meta-arguments) below.)
|
|
|
|
### Documentation for Resource Types
|
|
|
|
Every provider has its own documentation, describing its resource
|
|
types and their arguments.
|
|
|
|
Most publicly available providers are distributed on the
|
|
[Public Terraform Registry](https://registry.terraform.io/browse/providers), which also
|
|
hosts their documentation. When viewing a provider's page on the OpenTofu
|
|
Registry, you can click the "Documentation" link in the header to browse its
|
|
documentation. Provider documentation on the registry is versioned, and you can
|
|
use the dropdown version menu in the header to switch which version's
|
|
documentation you are viewing.
|
|
|
|
To browse the publicly available providers and their documentation, see the
|
|
[Public Terraform Registry](https://registry.terraform.io/browse/providers).
|
|
|
|
:::note
|
|
Provider documentation previously existed as part of OpenTofu's core documentation. Although some provider documentation
|
|
might still be hosted here, the Public OpenTofu Registry is now the main home for all
|
|
public provider docs.
|
|
:::
|
|
|
|
## Resource Behavior
|
|
|
|
For more information about how OpenTofu manages resources when applying a
|
|
configuration, see
|
|
[Resource Behavior](../../language/resources/behavior.mdx).
|
|
|
|
## Removing Resources
|
|
|
|
If you remove a resource block from your configuration, OpenTofu will destroy it as a default behavior.
|
|
|
|
However, there are instances when you want to remove a resource from your configuration without destroying the
|
|
corresponding infrastructure object. In such cases, you can remove it from the [OpenTofu state](../../language/state/index.mdx)
|
|
while allowing it to persist in the remote system.
|
|
|
|
To achieve this, follow these steps:
|
|
1. Delete the resource from your configuration.
|
|
2. Add a removed block instead, specifying the resource address you want to "forget" in the `from` attribute.
|
|
3. Specify the `lifecycle.destroy = false`
|
|
|
|
For example:
|
|
```hcl
|
|
removed {
|
|
from = aws_instance.web
|
|
lifecycle {
|
|
destroy = false
|
|
}
|
|
}
|
|
```
|
|
|
|
:::note
|
|
The address in the `from` attribute cannot include instance keys (for example, "aws_instance.web[0]").
|
|
:::
|
|
:::note
|
|
The `lifecycle.destroy` can be also `true`, case in which OpenTofu will behave just like the resource was deleted from the configuration.
|
|
Though, we allow this since such a `removed` block can be used as historical hint about the previously existing resource.
|
|
:::
|
|
|
|
:::warning
|
|
The `lifecycle` block is not required, but it's highly recommended to be added. OpenTofu will also generate a warning if it finds any
|
|
`removed` block without a `lifecycle` block defined inside. This is just to ensure that the user adding the `removed` block
|
|
is indicating clearly what the block is meant to do.
|
|
:::
|
|
|
|
Upon executing `tofu plan`, OpenTofu will indicate that the resource is slated for removal from the state but will not
|
|
be destroyed.
|
|
|
|
The `removed` blocks do also support inner `provisioner` blocks. This is useful when the `resource` that is targeted to be removed
|
|
was having `provisioner` blocks that the user wants to have executed before destroying the actual resource.
|
|
```hcl
|
|
removed {
|
|
from = aws_s3_bucket.example
|
|
lifecycle {
|
|
destroy = true
|
|
}
|
|
provisioner "local-exec" {
|
|
when = destroy
|
|
command = "echo 'destroying bucket ${self.bucket}'"
|
|
}
|
|
}
|
|
```
|
|
The `command` field do support references only the `self` object, `each.key` and `count.index`, which represents the information that OpenTofu is still having
|
|
in the state about the targeted `resource`.
|
|
|
|
The `provisioner` block will be executed only when the `removed` block is configured in a specific way:
|
|
- `lifecycle.destroy = true`
|
|
- `provisioner.when = destroy`
|
|
|
|
In any other cases, the execution will be skipped.
|
|
|
|
For more information about provisioners, you can refer to this [page](./provisioners/syntax.mdx).
|
|
|
|
## Meta-Arguments
|
|
|
|
The OpenTofu language defines several meta-arguments, which can be used with
|
|
any managed 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](behavior.mdx#lifecycle-customizations)
|
|
- [`provisioner`, for taking extra actions after resource creation](../../language/resources/provisioners/syntax.mdx)
|
|
|
|
## Custom Condition Checks
|
|
|
|
You can use `precondition` and `postcondition` blocks to specify assumptions and guarantees about how the resource operates. The following example creates a precondition that checks whether the AMI is properly configured.
|
|
|
|
```hcl
|
|
resource "aws_instance" "example" {
|
|
instance_type = "t2.micro"
|
|
ami = "ami-abc123"
|
|
|
|
lifecycle {
|
|
# The AMI ID must refer to an AMI that contains an operating system
|
|
# for the `x86_64` architecture.
|
|
precondition {
|
|
condition = data.aws_ami.example.architecture == "x86_64"
|
|
error_message = "The selected AMI must be for the x86_64 architecture."
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
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.
|
|
|
|
## Operation Timeouts
|
|
|
|
Some resource types provide a special `timeouts` nested block argument that
|
|
allows you to customize how long certain operations are allowed to take
|
|
before being considered to have failed.
|
|
For example, [`aws_db_instance`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance)
|
|
allows configurable timeouts for `create`, `update` and `delete` operations.
|
|
|
|
Timeouts are handled entirely by the resource type implementation in the
|
|
provider, but resource types offering these features follow the convention
|
|
of defining a child block called `timeouts` that has a nested argument
|
|
named after each operation that has a configurable timeout value.
|
|
Each of these arguments takes a string representation of a duration, such
|
|
as `"60m"` for 60 minutes, `"10s"` for ten seconds, or `"2h"` for two hours.
|
|
|
|
```hcl
|
|
resource "aws_db_instance" "example" {
|
|
# ...
|
|
|
|
timeouts {
|
|
create = "60m"
|
|
delete = "2h"
|
|
}
|
|
}
|
|
```
|
|
|
|
The set of configurable operations is chosen by each resource type. Most
|
|
resource types do not support the `timeouts` block at all. Consult the
|
|
documentation for each resource type to see which operations it offers
|
|
for configuration, if any.
|
|
|
|
## Write-only attributes
|
|
|
|
Many managed resources now offer write-only attributes as an alternative to older attributes which existed before the concept of ephemeral was added.
|
|
As an example, see [aws_secretsmanager_secret_version](https://search.opentofu.org/provider/hashicorp/aws/v6.11.0/docs/resources/secretsmanager_secret_version) and its `secret_string_wo` alternative for `secret_string`).
|
|
Additional documentation is available for [write-only attributes](../ephemerality/write-only-attributes.mdx)
|