Merge pull request #24635 from hashicorp/pselle/docs-mod-count
Docs for count/for_each on modules
This commit is contained in:
commit
ab101f99df
|
@ -155,7 +155,7 @@ described in more detail in other sections:
|
|||
If not specified, the child module inherits all of the default (un-aliased)
|
||||
provider configurations from the calling module.
|
||||
|
||||
In addition to the above, the argument names `count`, `for_each` and
|
||||
In addition to the above, the argument names `depends_on` and
|
||||
`lifecycle` are not currently used by Terraform but are reserved for planned
|
||||
future features.
|
||||
|
||||
|
@ -361,25 +361,23 @@ setting inside a `terraform` block.
|
|||
|
||||
## Multiple Instances of a Module
|
||||
|
||||
A particular module source can be instantiated multiple times:
|
||||
Use the `count` or `for_each` arguments to create multiple instances of a module.
|
||||
These arguments have the same syntax and type constraints as
|
||||
[`count`](./resources.html#count-multiple-resource-instances-by-count) and
|
||||
[`for_each`](./resources.html#for_each-multiple-resource-instances-defined-by-a-map-or-set-of-strings)
|
||||
as defined for managed resources.
|
||||
|
||||
```hcl
|
||||
# my_buckets.tf
|
||||
|
||||
module "assets_bucket" {
|
||||
source = "./publish_bucket"
|
||||
name = "assets"
|
||||
}
|
||||
|
||||
module "media_bucket" {
|
||||
source = "./publish_bucket"
|
||||
name = "media"
|
||||
module "bucket" {
|
||||
for_each = toset(["assets", "media"])
|
||||
source = "./publish_bucket"
|
||||
name = "${each.key}_bucket"
|
||||
}
|
||||
```
|
||||
|
||||
```hcl
|
||||
# publish_bucket/bucket-and-cloudfront.tf
|
||||
|
||||
variable "name" {} # this is the input parameter of the module
|
||||
|
||||
resource "aws_s3_bucket" "example" {
|
||||
|
@ -396,18 +394,23 @@ subdirectory. That module has configuration to create an S3 bucket. The module
|
|||
wraps the bucket and all the other implementation details required to configure
|
||||
a bucket.
|
||||
|
||||
We can then instantiate the module multiple times in our configuration by
|
||||
giving each instance a unique name -- here `module "assets_bucket"` and
|
||||
`module "media_bucket"` -- whilst specifying the same `source` value.
|
||||
We declare multiple module instances by using the `for_each` attribute,
|
||||
which accepts a map (with string keys) or a set of strings as its value. Additionally,
|
||||
we use the `each.key` in our module block, because the
|
||||
[`each`](/docs/configuration/resources.html#the-each-object) object is available when
|
||||
we have declared `for_each` on the module block. When using the `count` argument, the
|
||||
[`count`](/docs/configuration/resources.html#the-count-object) object is available.
|
||||
|
||||
Resources from child modules are prefixed with `module.<module-instance-name>`
|
||||
when displayed in plan output and elsewhere in the UI. For example, the
|
||||
`./publish_bucket` module contains `aws_s3_bucket.example`, and so the two
|
||||
instances of this module produce S3 bucket resources with [_resource addresses_](/docs/internals/resource-addressing.html)
|
||||
`module.assets_bucket.aws_s3_bucket.example` and `module.media_bucket.aws_s3_bucket.example`
|
||||
respectively. These full addresses are used within the UI and on the command
|
||||
line, but are not valid within interpolation expressions due to the
|
||||
encapsulation behavior described above.
|
||||
Resources from child modules are prefixed with `module.module_name[module index]`
|
||||
when displayed in plan output and elsewhere in the UI. For a module with without
|
||||
`count` or `for_each`, the address will not contain the module index as the module's
|
||||
name suffices to reference the module.
|
||||
|
||||
In our example, the `./publish_bucket` module contains `aws_s3_bucket.example`, and so the two
|
||||
instances of this module produce S3 bucket resources with [resource addresses](/docs/internals/resource-addressing.html) of `module.bucket["assets"].aws_s3_bucket.example`
|
||||
and `module.bucket["media"].aws_s3_bucket.example` respectively. These full addresses
|
||||
are used within the UI and on the command line, but only [outputs](docs/configuration/outputs.html)
|
||||
from a module can be referenced from elsewhere in your configuration.
|
||||
|
||||
When refactoring an existing configuration to introduce modules, moving
|
||||
resource blocks between modules causes Terraform to see the new location
|
||||
|
@ -415,10 +418,64 @@ as an entirely separate resource to the old. Always check the execution plan
|
|||
after performing such actions to ensure that no resources are surprisingly
|
||||
deleted.
|
||||
|
||||
Each instance of a module may optionally have different providers passed to it
|
||||
using the `providers` argument described above. This can be useful in situations
|
||||
where, for example, a duplicated set of resources must be created across
|
||||
several regions or datacenters.
|
||||
### Limitations when using module expansion
|
||||
|
||||
Modules using `count` or `for_each` cannot pass different sets of providers to different instances.
|
||||
This is because when a module instance is destroyed (such as a key-value being removed from the
|
||||
`for_each` map), the provider must be available in order to perform the destroy. You can pass
|
||||
different sets of providers by using multiple `module` blocks:
|
||||
|
||||
```
|
||||
# my_buckets.tf
|
||||
|
||||
provider "aws" {
|
||||
alias = "usw1"
|
||||
region = "us-west-1"
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
alias = "usw2"
|
||||
region = "us-west-2"
|
||||
}
|
||||
|
||||
provider "google" {
|
||||
alias = "usw1"
|
||||
credentials = "${file("account.json")}"
|
||||
project = "my-project-id"
|
||||
region = "us-west1"
|
||||
zone = "us-west1-a"
|
||||
}
|
||||
|
||||
provider "google" {
|
||||
alias = "usw2"
|
||||
credentials = "${file("account.json")}"
|
||||
project = "my-project-id"
|
||||
region = "us-west2"
|
||||
zone = "us-west2-a"
|
||||
}
|
||||
|
||||
module "bucket_w1" {
|
||||
source = "./publish_bucket"
|
||||
providers = {
|
||||
aws.src = "aws.usw1"
|
||||
google.src = "google.usw2"
|
||||
}
|
||||
}
|
||||
|
||||
module "bucket_w2" {
|
||||
source = "./publish_bucket"
|
||||
providers = {
|
||||
aws.src = "aws.usw2"
|
||||
google.src = "google.usw2"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Each module block may optionally have different providers passed to it
|
||||
using the [`providers`](/docs/configuration/modules.html#passing-providers-explicitly)
|
||||
argument. This can be useful in situations where, for example, a duplicated set of
|
||||
resources must be created across several regions or datacenters.
|
||||
|
||||
|
||||
## Tainting resources within a module
|
||||
|
||||
|
|
|
@ -16,19 +16,37 @@ larger infrastructure. An address is made up of two parts:
|
|||
[module path][resource spec]
|
||||
```
|
||||
|
||||
__Module path__:
|
||||
## Module path
|
||||
|
||||
A module path addresses a module within the tree of modules. It takes the form:
|
||||
|
||||
```
|
||||
module.A.module.B.module.C...
|
||||
module.module_name[module index]
|
||||
```
|
||||
|
||||
Multiple modules in a path indicate nesting. If a module path is specified
|
||||
without a resource spec, the address applies to every resource within the
|
||||
module. If the module path is omitted, this addresses the root module.
|
||||
* `module` - Module keyword indicating a child module (non-root). Multiple `module`
|
||||
keywords in a path indicate nesting.
|
||||
* `module_name` - User-defined name of the module.
|
||||
* `[module index]` - (Optional) [Index](#index-values-for-modules-and-resources) into a
|
||||
module with multiple instances, surrounded by square brace characters (`[` and `]`).
|
||||
|
||||
__Resource spec__:
|
||||
An address without a resource spec, i.e. `module.foo` applies to every resource within
|
||||
the module if a single module, or all instances of a module if a module has multiple instances.
|
||||
To address all resources of a particular module instance, include the module index in the address,
|
||||
such as `module.foo[0]`.
|
||||
|
||||
If the module path is omitted, the address applies to the root module.
|
||||
|
||||
An example of the `module` keyword delineating between two modules that have multiple instances:
|
||||
|
||||
```
|
||||
module.foo[0].module.bar["a"]
|
||||
```
|
||||
|
||||
-> Module index only applies to modules in Terraform v0.13 or later, as in earlier
|
||||
versions of Terraform, a module could not have multiple instances.
|
||||
|
||||
## Resource spec
|
||||
|
||||
A resource spec addresses a specific resource in the config. It takes the form:
|
||||
|
||||
|
@ -38,15 +56,17 @@ resource_type.resource_name[resource index]
|
|||
|
||||
* `resource_type` - Type of the resource being addressed.
|
||||
* `resource_name` - User-defined name of the resource.
|
||||
* `[resource index]` - an optional index into a resource with multiple
|
||||
instances, surrounded by square brace characters (`[` and `]`).
|
||||
* `[resource index]` - (Optional) [Index](#index-values-for-modules-and-resources)
|
||||
into a resource with multiple instances, surrounded by square brace characters (`[` and `]`).
|
||||
|
||||
-> In Terraform v0.12 and later, a resource spec without a module path prefix
|
||||
matches only resources in the root module. In earlier versions, a resource spec
|
||||
without a module path prefix will match resources with the same type and name
|
||||
in any descendent module.
|
||||
|
||||
__Resource index__:
|
||||
## Index values for Modules and Resources
|
||||
|
||||
The following specifications apply to index values on modules and resources with multiple instances:
|
||||
|
||||
* `[N]` where `N` is a `0`-based numerical index into a resource with multiple
|
||||
instances specified by the `count` meta-argument. Omitting an index when
|
||||
|
|
Loading…
Reference in New Issue