mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-21 10:47:34 -05:00
Over time the discussion about "lifecycle" blocks in the documentation became confusing because the docs originally written for managed resource lifecycle got partially generalized for resources of other modes and for module calls, even though each of those has a completely different lifecycle and thus a different set of lifecycle settings. This is a first pass at trying to reorganize that so that the "lifecycle" page is really just an index of all of the different kinds of lifecycle block that exist in the language, while the main documentation for each use of that block type now belongs with the documentation of the block it's nested within. While working on this I also found that there was some duplication inside the "data sources" page where the same information was described multiple times, and a few other cases where things had become inconsistent over time. This also includes a little extra content to try to clarify the difference between managed, data, and ephemeral resources and to make it explicit that the "Resources" section is focused only on managed resources because that is the primary resource mode. As usual there's lots more that could be done here -- this documentation has gradually evolved over time and is full of weird quirks due to that evolution -- but I decided to draw a line here so that the diff wouldn't get too large. Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
240 lines
9.1 KiB
Plaintext
240 lines
9.1 KiB
Plaintext
---
|
|
description: >-
|
|
Modules are containers for multiple resources that are used together in
|
|
configurations. Learn how to call one module from another and access module
|
|
output.
|
|
---
|
|
|
|
# Module Blocks
|
|
|
|
A _module_ is a container for multiple resources that are used together.
|
|
|
|
Every OpenTofu configuration has at least one module, known as its
|
|
_root module_, which consists of the resources defined in the `.tf` and `.tofu`
|
|
files in the main working directory.
|
|
|
|
A module can call other modules, which lets you include the child module's
|
|
resources into the configuration in a concise way. Modules
|
|
can also be called multiple times, either within the same configuration or
|
|
in separate configurations, allowing resource configurations to be packaged
|
|
and re-used.
|
|
|
|
This page describes how to call one module from another. For more information
|
|
about creating re-usable child modules, see [Module Development](../../language/modules/develop/index.mdx).
|
|
|
|
## Calling a Child Module
|
|
|
|
To _call_ a module means to include the contents of that module into the
|
|
configuration with specific values for its
|
|
[input variables](../../language/values/variables.mdx). Modules are called
|
|
from within other modules using `module` blocks:
|
|
|
|
```hcl
|
|
module "servers" {
|
|
source = "./app-cluster"
|
|
|
|
servers = 5
|
|
}
|
|
```
|
|
|
|
A module that includes a `module` block like this is the _calling module_ of the
|
|
child module.
|
|
|
|
The label immediately after the `module` keyword is a local name, which the
|
|
calling module can use to refer to this instance of the module.
|
|
|
|
Within the block body (between `{` and `}`) are the arguments for the module.
|
|
Module calls use the following kinds of arguments:
|
|
|
|
- The `source` argument is mandatory for all modules.
|
|
|
|
- The `version` argument is recommended for modules from a registry.
|
|
|
|
- Most other arguments correspond to [input variables](../../language/values/variables.mdx)
|
|
defined by the module. (The `servers` argument in the example above is one of
|
|
these.)
|
|
|
|
- OpenTofu defines a few other meta-arguments that can be used with all
|
|
modules, including `for_each` and `depends_on`.
|
|
|
|
### Source
|
|
|
|
All modules **require** a `source` argument, which is a meta-argument defined by
|
|
OpenTofu. Its value is either the path to a local directory containing the
|
|
module's configuration files, or a remote module source that OpenTofu should
|
|
download and use. For more information on
|
|
possible values for this argument, see [Module Sources](../../language/modules/sources.mdx).
|
|
|
|
The same source address can be specified in multiple `module` blocks to create
|
|
multiple copies of the resources defined within, possibly with different
|
|
variable values.
|
|
|
|
After adding, removing, or modifying `module` blocks, you must re-run
|
|
`tofu init` to allow OpenTofu the opportunity to adjust the installed
|
|
modules. By default this command will not upgrade an already-installed module;
|
|
use the `-upgrade` option to instead upgrade to the newest available version.
|
|
|
|
### Version
|
|
|
|
When using modules installed from a module registry, we recommend explicitly
|
|
constraining the acceptable version numbers to avoid unexpected or unwanted
|
|
changes.
|
|
|
|
Use the `version` argument in the `module` block to specify versions:
|
|
|
|
```shell
|
|
module "consul" {
|
|
source = "hashicorp/consul/aws"
|
|
version = "0.0.5"
|
|
|
|
servers = 3
|
|
}
|
|
```
|
|
|
|
The `version` argument accepts a [version constraint string](../../language/expressions/version-constraints.mdx).
|
|
OpenTofu will use the newest installed version of the module that meets the
|
|
constraint; if no acceptable versions are installed, it will download the newest
|
|
version that meets the constraint.
|
|
|
|
Version constraints are supported only for modules installed from a module
|
|
registry, such as the [Public OpenTofu Registry](https://registry.opentofu.org/)
|
|
or any [TACOS](../../intro/tacos.mdx) (TF Automation and Collaboration Software) private modules registry.
|
|
Other module sources can provide their own versioning mechanisms within the
|
|
source string itself, or might not support versions at all. In particular,
|
|
modules sourced from local file paths do not support `version`; since
|
|
they're loaded from the same source repository, they always share the same
|
|
version as their caller.
|
|
|
|
### Meta-arguments
|
|
|
|
Along with `source` and `version`, OpenTofu defines a few more
|
|
optional meta-arguments that have special meaning across all modules,
|
|
described in more detail in the following pages:
|
|
|
|
- `count` - Creates multiple instances of a module from a single `module` block.
|
|
See [the `count` page](../../language/meta-arguments/count.mdx)
|
|
for details.
|
|
|
|
- `for_each` - Creates multiple instances of a module from a single `module`
|
|
block. See
|
|
[the `for_each` page](../../language/meta-arguments/for_each.mdx)
|
|
for details.
|
|
|
|
- `providers` - Passes provider configurations to a child module. See
|
|
[the `providers` page](../../language/meta-arguments/module-providers.mdx)
|
|
for details. If not specified, the child module inherits all of the default
|
|
(un-aliased) provider configurations from the calling module.
|
|
|
|
- `depends_on` - Creates explicit dependencies between the entire
|
|
module and the listed targets. See
|
|
[the `depends_on` page](../../language/meta-arguments/depends_on.mdx)
|
|
for details.
|
|
|
|
- `lifecycle` - Allows lifecycle customizations for modules, as described
|
|
in [Module Lifecycle](#module-lifecycle) below.
|
|
|
|
## Module Lifecycle
|
|
|
|
A `lifecycle` block inside a `module` block allows some customization of
|
|
OpenTofu's behavior relating to the overall module call, rather than to
|
|
individual resources inside the module.
|
|
|
|
```hcl
|
|
module "example" {
|
|
# ...normal module call arguments...
|
|
|
|
lifecycle {
|
|
# ...lifecycle arguments...
|
|
}
|
|
}
|
|
```
|
|
|
|
Module call lifecycle currently supports only a single argument:
|
|
|
|
* `enabled` (bool) - Controls whether the module call will be used by OpenTofu.
|
|
When set to `false`, the content of the module is excluded from the
|
|
configuration as if the call didn't exist. When set to `true` (the default),
|
|
the module operates normally.
|
|
|
|
For more information, refer to [the `enabled` meta-argument](../../language/meta-arguments/enabled.mdx).
|
|
|
|
## Accessing Module Output Values
|
|
|
|
The resources defined in a module are encapsulated, so the calling module
|
|
cannot access their attributes directly. However, the child module can
|
|
declare [output values](../../language/values/outputs.mdx) to selectively
|
|
export certain values to be accessed by the calling module.
|
|
|
|
For example, if the `./app-cluster` module referenced in the example above
|
|
exported an output value named `instance_ids` then the calling module
|
|
can reference that result using the expression `module.servers.instance_ids`:
|
|
|
|
```hcl
|
|
resource "aws_elb" "example" {
|
|
# ...
|
|
|
|
instances = module.servers.instance_ids
|
|
}
|
|
```
|
|
|
|
For more information about referring to named values, see
|
|
[Expressions](../../language/expressions/index.mdx).
|
|
|
|
## Transferring Resource State Into Modules
|
|
|
|
Moving `resource` blocks from one module into several child modules causes
|
|
OpenTofu to see the new location as an entirely different resource. As a
|
|
result, OpenTofu plans to destroy all resource instances at the old address
|
|
and create new instances at the new address.
|
|
|
|
To preserve existing objects, you can use
|
|
[refactoring blocks](../../language/modules/develop/refactoring.mdx) to record the old and new
|
|
addresses for each resource instance. This directs OpenTofu to treat existing
|
|
objects at the old addresses as if they had originally been created at the
|
|
corresponding new addresses.
|
|
|
|
## Replacing resources within a module
|
|
|
|
You may have an object that needs to be replaced with a new object for a reason
|
|
that isn't automatically visible to OpenTofu, such as if a particular virtual
|
|
machine is running on degraded underlying hardware. In this case, you can use
|
|
[the `-replace=...` planning option](../../cli/commands/plan.mdx#replace-address)
|
|
to force OpenTofu to propose replacing that object.
|
|
|
|
If the object belongs to a resource within a nested module, specify the full
|
|
path to that resource including all of the nested module steps leading to it.
|
|
For example:
|
|
|
|
```shellsession
|
|
$ tofu plan -replace=module.example.aws_instance.example
|
|
```
|
|
|
|
The above selects a `resource "aws_instance" "example"` declared inside a
|
|
`module "example"` child module declared inside your root module.
|
|
|
|
Because replacing is a very disruptive action, OpenTofu only allows selecting
|
|
individual resource instances. There is no syntax to force replacing _all_
|
|
resource instances belonging to a particular module.
|
|
|
|
## Removing a module
|
|
The same as any `resource`, a `module` can be removed as well by using the `removed` refactoring block.
|
|
When you remove the configuration of a module, OpenTofu will destroy all the resources that the removed module was managing.
|
|
|
|
There are cases when the module is wanted to be removed from the configuration (and from the state) but the resources managed by it should stay untouched.
|
|
To achieve this, follow these steps:
|
|
1. Delete the module from your configuration.
|
|
2. Add a removed block instead, specifying the module address you want to "forget" in the `from` attribute.
|
|
3. Specify the `lifecycle.destroy = false`
|
|
|
|
```hcl
|
|
removed {
|
|
from = module.some_module
|
|
lifecycle {
|
|
destroy = false
|
|
}
|
|
}
|
|
```
|
|
:::note
|
|
In contrast with `resource` blocks removal, `removed` blocks pointing to modules, do not allow usage of `provisioners`.
|
|
:::
|