diff --git a/website/docs/configuration/modules.html.md b/website/docs/configuration/modules.html.md index 400e7449e..fc4caa018 100644 --- a/website/docs/configuration/modules.html.md +++ b/website/docs/configuration/modules.html.md @@ -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" { +module "bucket" { + for_each = toset(["assets", "media"]) source = "./publish_bucket" - name = "assets" -} - -module "media_bucket" { - source = "./publish_bucket" - name = "media" + 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.` -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 @@ -416,9 +419,8 @@ 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. +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 diff --git a/website/docs/internals/resource-addressing.html.markdown b/website/docs/internals/resource-addressing.html.markdown index e88c2cead..ec157e271 100644 --- a/website/docs/internals/resource-addressing.html.markdown +++ b/website/docs/internals/resource-addressing.html.markdown @@ -21,12 +21,24 @@ __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 into a module with multiple + instances, surrounded by square brace characters (`[` and `]`). + +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. + +-> 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__: @@ -38,7 +50,7 @@ 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 + * `[resource index]` - (Optional) Index 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 @@ -46,7 +58,9 @@ 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