---
description: >-
  The meta-arguments in a lifecycle block allow you to customize resource
  behavior.
---

# The `lifecycle` Meta-Argument

The [Resource Behavior](../../language/resources/behavior.mdx) page describes the general lifecycle for resources. Some details of
that behavior can be customized using the special nested `lifecycle` block
within a resource block body:

```hcl
resource "azurerm_resource_group" "example" {
  # ...

  lifecycle {
    create_before_destroy = true
  }
}
```

## Syntax and Arguments

`lifecycle` is a nested block that can appear within a resource block.
The `lifecycle` block and its contents are meta-arguments, available
for all `resource` blocks regardless of type.

The arguments available within a `lifecycle` block are `create_before_destroy`,
`prevent_destroy`, `ignore_changes`, and `replace_triggered_by`.

* `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 to the state file. You cannot override `create_before_destroy`
  to `false` on resource B because that would imply dependency cycles in the graph.

  Destroy provisioners of this resource do not run if `create_before_destroy`
  is set to `true`. This [GitHub issue](https://github.com/hashicorp/terraform/issues/13549) contains more details.

* `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
  apply, note that this setting does not prevent the remote object from
  being destroyed if the `resource` block were removed from configuration
  entirely: in that case, the `prevent_destroy` setting is removed along
  with it, and so OpenTofu will allow the destroy operation to succeed.

* `ignore_changes` (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.

  ```hcl
  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,
      ]
    }
  }
  ```

  Instead of a list, the special keyword `all` may be used to instruct
  OpenTofu to ignore _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.

* `replace_triggered_by` (list of resource or attribute references) -
  Replaces the resource when any of the referenced
  items change. Supply a list of expressions referencing managed resources,
  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
  reference specific instances of other resources that are configured with the
  same count or collection.

  References trigger replacement in the following conditions:

  - If the reference is to a resource with multiple instances, a plan to
    update or replace any instance will trigger replacement.
  - If the reference is to a single resource instance, a plan to update or
    replace that instance will trigger replacement.
  - If the reference is to a single attribute of a resource instance, any
    change to the attribute value will trigger replacement.

  You can only reference managed resources in `replace_triggered_by`
  expressions. This lets you modify these expressions without forcing
  replacement.

  ```hcl
  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](../../language/resources/tf-data.mdx).

## Custom Condition Checks

You can add `precondition` and `postcondition` blocks with a `lifecycle` block to specify assumptions and guarantees about how resources and data sources operate. The following examples 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 Conditions](../../language/expressions/custom-conditions.mdx#preconditions-and-postconditions) for more details.

## Literal Values Only

The `lifecycle` settings all affect how OpenTofu constructs and traverses
the dependency graph. As a result, only literal values can be used because
the processing happens too early for arbitrary expression evaluation.
