353 lines
11 KiB
Markdown
353 lines
11 KiB
Markdown
---
|
|
layout: "docs"
|
|
page_title: "Configuring Resources"
|
|
sidebar_current: "docs-config-resources"
|
|
description: |-
|
|
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.
|
|
---
|
|
|
|
# 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](/docs/configuration/syntax.html)
|
|
already.
|
|
|
|
## Example
|
|
|
|
A resource configuration looks like the following:
|
|
|
|
```hcl
|
|
resource "aws_instance" "web" {
|
|
ami = "ami-408c7f28"
|
|
instance_type = "t1.micro"
|
|
}
|
|
```
|
|
|
|
## Description
|
|
|
|
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](/docs/providers/index.html).
|
|
|
|
### Meta-parameters
|
|
|
|
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`](#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](#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](#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 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.
|
|
|
|
-> Interpolations are not currently supported in the `lifecycle` configuration block (see [issue #3116](https://github.com/hashicorp/terraform/issues/3116))
|
|
|
|
### Timeouts
|
|
|
|
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](/docs/providers/aws/r/db_instance.html#timeouts)
|
|
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:
|
|
|
|
```hcl
|
|
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`.
|
|
|
|
### Explicit Dependencies
|
|
|
|
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](/docs/configuration/interpolation.html). 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:
|
|
|
|
- Resources are `TYPE.NAME`, such as `aws_instance.web`.
|
|
- Modules are `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:
|
|
|
|
```hcl
|
|
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 use `depends_on` to determine if Terraform
|
|
could automatically do this a better way.
|
|
|
|
### Connection block
|
|
|
|
Within a resource, you can optionally have a **connection block**.
|
|
Connection blocks describe to Terraform how to connect to the
|
|
resource for
|
|
[provisioning](/docs/provisioners/index.html). 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](/docs/provisioners/connection.html).
|
|
|
|
### Provisioners
|
|
|
|
Within a resource, you can specify zero or more **provisioner
|
|
blocks**. Provisioner blocks configure
|
|
[provisioners](/docs/provisioners/index.html).
|
|
|
|
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`](#count), it is
|
|
common to want each instance to have a different value for a given attribute.
|
|
|
|
You can use the `${count.index}`
|
|
[interpolation](/docs/configuration/interpolation.html) along with a map
|
|
[variable](/docs/configuration/variables.html) to accomplish this.
|
|
|
|
For example, here's how you could create three [AWS
|
|
Instances](/docs/providers/aws/r/instance.html) each with their own
|
|
static IP address:
|
|
|
|
```hcl
|
|
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](/docs/providers/aws/r/subnet.html) ids vs referencing a specific subnet in the list you can use this syntax:
|
|
|
|
```hcl
|
|
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]}"
|
|
}
|
|
```
|
|
|
|
## 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:
|
|
|
|
```hcl
|
|
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](/docs/configuration/providers.html).
|
|
|
|
```hcl
|
|
provider "aws" {
|
|
alias = "west"
|
|
|
|
# ...
|
|
}
|
|
```
|
|
|
|
If no `provider` field is specified, the default provider is used.
|
|
|
|
## Syntax
|
|
|
|
The full syntax is:
|
|
|
|
```text
|
|
resource TYPE NAME {
|
|
CONFIG ...
|
|
[count = COUNT]
|
|
[depends_on = [NAME, ...]]
|
|
[provider = PROVIDER]
|
|
|
|
[LIFECYCLE]
|
|
|
|
[CONNECTION]
|
|
[PROVISIONER ...]
|
|
}
|
|
```
|
|
|
|
where `CONFIG` is:
|
|
|
|
```text
|
|
KEY = VALUE
|
|
|
|
KEY {
|
|
CONFIG
|
|
}
|
|
```
|
|
|
|
where `LIFECYCLE` is:
|
|
|
|
```text
|
|
lifecycle {
|
|
[create_before_destroy = true|false]
|
|
[prevent_destroy = true|false]
|
|
[ignore_changes = [ATTRIBUTE NAME, ...]]
|
|
}
|
|
```
|
|
|
|
where `CONNECTION` is:
|
|
|
|
```text
|
|
connection {
|
|
KEY = VALUE
|
|
...
|
|
}
|
|
```
|
|
|
|
where `PROVISIONER` is:
|
|
|
|
```text
|
|
provisioner NAME {
|
|
CONFIG ...
|
|
|
|
[when = "create"|"destroy"]
|
|
[on_failure = "continue"|"fail"]
|
|
|
|
[CONNECTION]
|
|
}
|
|
```
|