| --- |
| page_title: Resources - Configuration Language |
| description: >- |
| Resources correspond to infrastructure objects like virtual networks or |
| compute instances. Learn about resource types, syntax, behavior, and |
| arguments. |
| --- |
| |
| # Resource Blocks |
| |
| > **Hands-on:** Try the [Terraform: Get Started](/terraform/tutorials/aws-get-started?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorials. |
| |
| _Resources_ are the most important element in the Terraform language. |
| Each resource block describes one or more infrastructure objects, such |
| as virtual networks, compute instances, or higher-level components such |
| as DNS records. |
| |
| For information about how Terraform manages resources after applying a configuration, refer to |
| [Resource Behavior](/terraform/language/resources/behavior). |
| |
| ## Resource Syntax |
| |
| A `resource` block declares a resource of a specific type |
| with a specific local name. Terraform uses the name when referring to the resource |
| in the same module, but it has no meaning outside that module's scope. |
| |
| In the following example, the `aws_instance` resource type is named `web`. The resource type and name must be unique within a module because they serve as an identifier for a given resource. |
| |
| ```hcl |
| resource "aws_instance" "web" { |
| ami = "ami-a1b2c3d4" |
| instance_type = "t2.micro" |
| } |
| ``` |
| |
| Within the block body (between `{` and `}`) are the configuration arguments |
| for the resource itself. The arguments often depend on the |
| resource type. In this example, both `ami` and `instance_type` are special |
| arguments 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 declarations can include more advanced features, such as single |
| resource declarations that produce multiple similar remote objects, but only |
| a small subset is required for initial use. |
| |
| ## 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 |
| |
| A [provider](/terraform/language/providers/requirements) is a plugin for Terraform |
| that offers a collection of resource types. Each resource type is implemented by a provider. A |
| provider provides resources to manage a single cloud or on-premises |
| infrastructure platform. Providers are distributed separately from Terraform, |
| but Terraform can automatically install most providers when initializing |
| a working directory. |
| |
| To manage resources, a Terraform module must specify the required providers. Refer to |
| [Provider Requirements](/terraform/language/providers/requirements) for additional information. |
| |
| Most providers need some configuration to access their remote API, |
| which is provided by the root module. Refer to |
| [Provider Configuration](/terraform/language/providers/configuration) for additional information. |
| |
| Based on a resource type's name, Terraform can usually determine which provider to use. |
| 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](/terraform/language/meta-arguments/resource-provider) |
| to manually choose a provider configuration. |
| |
| ### 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](/terraform/language/expressions) and other dynamic Terraform |
| language features. |
| |
| [Meta-arguments](#meta-arguments) are defined by Terraform |
| and apply across all resource types. |
| |
| ### Documentation for Resource Types |
| |
| Every Terraform provider has its own documentation, describing its resource |
| types and their arguments. |
| |
| Some provider documentation is still part of Terraform's core documentation, |
| but the [Terraform Registry](https://registry.terraform.io/browse/providers) |
| is the main home for all publicly available provider docs. |
| |
| When viewing a provider's page on the Terraform |
| Registry, you can click the **Documentation** link in the header to browse its |
| documentation. The documentation is versioned. To choose a different version of the provider documentation, click on the version in the provider breadcrumbs to choose a version from the drop-down menu. |
| |
| ## Meta-Arguments |
| |
| The Terraform language defines the following meta-arguments, which can be used with |
| any resource type to change the behavior of resources: |
| |
| - [`depends_on`, for specifying hidden dependencies](/terraform/language/meta-arguments/depends_on) |
| - [`count`, for creating multiple resource instances according to a count](/terraform/language/meta-arguments/count) |
| - [`for_each`, to create multiple instances according to a map, or set of strings](/terraform/language/meta-arguments/for_each) |
| - [`provider`, for selecting a non-default provider configuration](/terraform/language/meta-arguments/resource-provider) |
| - [`lifecycle`, for lifecycle customizations](/terraform/language/meta-arguments/lifecycle) |
| - [`provisioner`, for taking extra actions after resource creation](/terraform/language/resources/provisioners/syntax) |
| |
| ## Removing Resources |
| |
| -> **Note:** The `removed` block is available in Terraform v1.7 and later. For earlier Terraform versions, you can use the [`terraform state rm` CLI command](/terraform/cli/commands/state/rm) as a separate step. |
| |
| To remove a resource from Terraform, simply delete the `resource` block from your Terraform configuration. |
| |
| By default, after you remove the `resource` block, Terraform will plan to destroy any real infrastructure object managed by that resource. |
| |
| Sometimes you may wish to remove a resource from your Terraform configuration without destroying the real infrastructure object it manages. In this case, the resource will be removed from the [Terraform state](/terraform/language/state), but the real infrastructure object will not be destroyed. |
| |
| To declare that a resource was removed from Terraform configuration but that its managed object should not be destroyed, remove the `resource` block from your configuration and replace it with a `removed` block: |
| |
| ```hcl |
| removed { |
| from = aws_instance.example |
| |
| lifecycle { |
| destroy = false |
| } |
| } |
| ``` |
| |
| The `from` argument is the address of the resource you want to remove, without any instance keys (such as "aws_instance.example[1]"). |
| |
| The `lifecycle` block is required. The `destroy` argument determines whether Terraform will attempt to destroy the object managed by the resource or not. A value of `false` means that Terraform will remove the resource from state without destroying it. |
| |
| A `removed` block may also contain a [Destroy-Time Provisioner](/terraform/language/resources/provisioners/syntax#destroy-time-provisioners), so that the provisioner can remain in the configuration even though the `resource` block has been removed. |
| |
| ```hcl |
| removed { |
| from = aws_instance.example |
| |
| lifecycle { |
| destroy = true |
| } |
| |
| provisioner "local-exec" { |
| when = destroy |
| command = "echo 'Instance ${self.id} has been destroyed.'" |
| } |
| } |
| ``` |
| |
| The same referencing rules apply as in normal destroy-time provisioners, with only `count.index`, `each.key`, and `self` allowed. The provisioner must specify `when = destroy`, and the `removed` block must use `destroy = true` in order for the provisioner to execute. |
| |
| ## 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 condition checks](/terraform/language/expressions/custom-conditions#preconditions-and-postconditions) |
| can help capture assumptions so that future maintainers |
| understand the configuration design and intent. They also return useful |
| information about errors earlier and in context, helping consumers to diagnose |
| issues in their configuration. |
| |
| ## 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. |