Resource Configuration

The most important thing you’ll configure with Terraform are resources. Resources are a component of your infrastructure. It might be some low level component such as a physical server, virtual machine, or container. Or it can be a higher level component such as an email provider, DNS record, or database provider.

This page assumes you’re familiar with the configuration syntax already.


A resource configuration looks like the following:

resource "aws_instance" "web" {
    ami = "ami-408c7f28"
    instance_type = "t1.micro"


The resource block creates a resource of the given TYPE (first parameter) and NAME (second parameter). The combination of the type and name must be unique.

Within the block (the { }) is configuration for the resource. The configuration is dependent on the type, and is documented for each resource type in the providers section.

There are meta-parameters available to all resources:

The lifecycle block allows the following keys to be set:

~> NOTE on create_before_destroy and dependencies: Resources that utilize the create_before_destroy key can only depend on other resources that also include create_before_destroy. Referencing a resource that does not include create_before_destroy will result in a dependency graph cycle.

~> NOTE on ignore_changes: Ignored attribute names can be matched by their name, not state ID. For example, if an aws_route_table has two routes defined and the ignore_changes list contains “route”, both routes will be ignored. Additionally you can also use a single entry with a wildcard (e.g. "*") which will match all attribute names. Using a partial string together with a wildcard (e.g. "rout*") is not supported.

Within a resource, you can optionally have a connection block. Connection blocks describe to Terraform how to connect to the resource for provisioning. This block doesn’t need to be present if you’re using only local provisioners, or if you’re not provisioning at all.

Resources provide some data on their own, such as an IP address, but other data must be specified by the user.

The full list of settings that can be specified are listed on the provisioner connection page.

Within a resource, you can specify zero or more provisioner blocks. Provisioner blocks configure provisioners.

Within the provisioner block is provisioner-specific configuration, much like resource-specific configuration.

Provisioner blocks can also contain a connection block (documented above). This connection block can be used to provide more specific connection info for a specific provisioner. An example use case might be to use a different user to log in for a single provisioner.

Using Variables With count

When declaring multiple instances of a resource using count, it is common to want each instance to have a different value for a given attribute.

You can use the ${count.index} interpolation along with a map variable to accomplish this.

For example, here’s how you could create three AWS Instances each with their own static IP address:

variable "instance_ips" {
  default = {
    "0" = ""
    "1" = ""
    "2" = ""

resource "aws_instance" "app" {
  count = "3"
  private_ip = "${lookup(var.instance_ips, count.index)}"
  # ...

Multiple Provider Instances

By default, a resource targets the provider based on its type. For example an aws_instance resource will target the “aws” provider. As of Terraform 0.5.0, a resource can target any provider by name.

The primary use case for this is to target a specific configuration of a provider that is configured multiple times to support multiple regions, etc.

To target another provider, set the provider field:

resource "aws_instance" "foo" {
	provider = "aws.west"

	# ...

The value of the field should be TYPE or TYPE.ALIAS. The ALIAS value comes from the alias field value when configuring the provider.

If no provider field is specified, the default (provider with no alias) provider is used.


The full syntax is:

resource TYPE NAME {
	[count = COUNT]
	[depends_on = [RESOURCE NAME, ...]]
	[provider = PROVIDER]



where CONFIG is:



where LIFECYCLE is:

lifecycle {
    [create_before_destroy = true|false]
    [prevent_destroy = true|false]
    [ignore_changes = [ATTRIBUTE NAME, ...]]

where CONNECTION is:

connection {


provisioner NAME {


See the source of this document at Terraform.io