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:
count
(int) - The number of identical resources to create. This doesn't apply to all resources. For details on using variables in conjunction with count, see Using Variables with count
below.
Modules don't currently support the
count
parameter.
depends_on
(list of strings) - Explicit dependencies that this resource has. These dependencies will be created before this resource. For syntax and other details, see the section below on explicit dependencies.
provider
(string) - The name of a specific provider to use for this resource. The name is in the format of TYPE.ALIAS
, for example, aws.west
. Where west
is set using the alias
attribute in a provider. See multiple provider instances.
lifecycle
(configuration block) - Customizes the lifecycle behavior of the resource. The specific options are documented below.
The lifecycle
block allows the following keys to be set:
create_before_destroy
(bool) - This flag is used to ensure the replacement of a resource is created before the original instance is destroyed. As an example, this can be used to create an new DNS record before removing an old record. prevent_destroy
(bool) - This flag provides extra protection against the destruction of a given resource. When this is set to true
, any plan that includes a destroy of this resource will return an error message. ignore_changes
(list of strings) - Customizes how diffs are evaluated for resources, allowing individual attributes to be ignored through changes. As an example, this can be used to ignore dynamic changes to the resource from external resources. Other meta-parameters cannot be ignored.
Ignored attribute names can be matched by their name, not state ID. For example, if an
aws_route_table
has two routes defined and theignore_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.
Interpolations are not currently supported in the
lifecycle
configuration block (see issue #3116)
Individual Resources may provide a timeouts
block to enable users to configure the amount of time a specific operation is allowed to take before being considered an error. For example, the aws_db_instance resource provides configurable timeouts for the create
, update
, and delete
operations. Any Resource that provides Timeouts will document the default values for that operation, and users can overwrite them in their configuration.
Example overwriting the create
and delete
timeouts:
resource "aws_db_instance" "timeout_example" { allocated_storage = 10 engine = "mysql" engine_version = "5.6.17" instance_class = "db.t1.micro" name = "mydb" # ... timeouts { create = "60m" delete = "2h" } }
Individual Resources must opt-in to providing configurable Timeouts, and attempting to configure the timeout for a Resource that does not support Timeouts, or overwriting a specific action that the Resource does not specify as an option, will result in an error. Valid units of time are s
, m
, h
.
Terraform ensures that dependencies are successfully created before a resource is created. During a destroy operation, Terraform ensures that this resource is destroyed before its dependencies.
A resource automatically depends on anything it references via interpolations. The automatically determined dependencies are all that is needed most of the time. You can also use the depends_on
parameter to explicitly define a list of additional dependencies.
The primary use case of explicit depends_on
is to depend on a side effect of another operation. For example: if a provisioner creates a file, and your resource reads that file, then there is no interpolation reference for Terraform to automatically connect the two resources. However, there is a causal ordering that needs to be represented. This is an ideal case for depends_on
. In most cases, however, depends_on
should be avoided and Terraform should be allowed to determine dependencies automatically.
The syntax of depends_on
is a list of resources and modules:
TYPE.NAME
, such as aws_instance.web
. module.NAME
, such as module.foo
. When a resource depends on a module, everything in that module must be created before the resource is created.
An example of a resource depending on both a module and resource is shown below. Note that depends_on
can contain any number of dependencies:
resource "aws_instance" "web" { depends_on = ["aws_instance.leader", "module.vpc"] }
Use sparingly!
depends_on
is rarely necessary. In almost every case, Terraform's automatic dependency system is the best-case scenario by having your resources depend only on what they explicitly use. Please think carefully before you usedepends_on
to determine if Terraform could automatically do this a better way.
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.
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" = "10.11.12.100" "1" = "10.11.12.101" "2" = "10.11.12.102" } } resource "aws_instance" "app" { count = "3" private_ip = "${lookup(var.instance_ips, count.index)}" # ... }
To reference a particular instance of a resource you can use resource.foo.*.id[#]
where #
is the index number of the instance.
For example, to create a list of all AWS subnet ids vs referencing a specific subnet in the list you can use this syntax:
resource "aws_vpc" "foo" { cidr_block = "198.18.0.0/16" } resource "aws_subnet" "bar" { count = 2 vpc_id = "${aws_vpc.foo.id}" cidr_block = "${cidrsubnet(aws_vpc.foo.cidr_block, 8, count.index)}" } output "vpc_id" { value = "${aws_vpc.foo.id}" } output "all_subnet_ids" { value = "${aws_subnet.bar.*.id}" } output "subnet_id_0" { value = "${aws_subnet.bar.*.id[0]}" } output "subnet_id_1" { value = "${aws_subnet.bar.*.id[1]}" }
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.
provider "aws" { alias = "west" # ... }
If no provider
field is specified, the default provider is used.
The full syntax is:
resource TYPE NAME { CONFIG ... [count = COUNT] [depends_on = [NAME, ...]] [provider = PROVIDER] [LIFECYCLE] [CONNECTION] [PROVISIONER ...] }
where CONFIG
is:
KEY = VALUE KEY { CONFIG }
where LIFECYCLE
is:
lifecycle { [create_before_destroy = true|false] [prevent_destroy = true|false] [ignore_changes = [ATTRIBUTE NAME, ...]] }
where CONNECTION
is:
connection { KEY = VALUE ... }
where PROVISIONER
is:
provisioner NAME { CONFIG ... [when = "create"|"destroy"] [on_failure = "continue"|"fail"] [CONNECTION] }
© 2018 HashiCorpLicensed under the MPL 2.0 License.
https://www.terraform.io/docs/configuration/resources.html