| --- | |
| 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`. | |
| ::: |