| --- | |
| description: >- | |
| Modules are containers for multiple resources that are used together in a | |
| configuration. Learn when to create modules and about module structure. | |
| --- | |
| # Creating Modules | |
| A _module_ is a container for multiple resources that are used together. | |
| You can use modules to create lightweight abstractions, so that you can | |
| describe your infrastructure in terms of its architecture, rather than | |
| directly in terms of physical objects. | |
| The `.tf` and/or `.tofu` files in your working directory when you run | |
| [`tofu plan`](../../../cli/commands/plan.mdx) or [`tofu apply`](../../../cli/commands/apply.mdx) | |
| together form the _root_ module. That module may [call other modules](../../../language/modules/syntax.mdx#calling-a-child-module) | |
| and connect them together by passing output values from one to input values | |
| of another. | |
| To learn how to _use_ modules, see [the Modules configuration section](../../../language/modules/index.mdx). | |
| This section is about _creating_ re-usable modules that other configurations | |
| can include using `module` blocks. | |
| ## Module structure | |
| Re-usable modules are defined using all of the same | |
| [configuration language](../../../language/index.mdx) concepts we use in root modules. | |
| Most commonly, modules use: | |
| * [Input variables](../../../language/values/variables.mdx) to accept values from | |
| the calling module. | |
| * [Output values](../../../language/values/outputs.mdx) to return results to the | |
| calling module, which it can then use to populate arguments elsewhere. | |
| * [Resources](../../../language/resources/index.mdx) to define one or more | |
| infrastructure objects that the module will manage. | |
| To define a module, create a new directory for it and place one or more `.tf` | |
| files inside just as you would do for a root module. OpenTofu can load modules | |
| either from local relative paths or from remote repositories; if a module will | |
| be re-used by lots of configurations you may wish to place it in its own | |
| version control repository. | |
| Modules can also call other modules using a `module` block, but we recommend | |
| keeping the module tree relatively flat and using [module composition](../../../language/modules/develop/composition.mdx) | |
| as an alternative to a deeply-nested tree of modules, because this makes | |
| the individual modules easier to re-use in different combinations. | |
| ## When to write a module | |
| In principle any combination of resources and other constructs can be factored | |
| out into a module, but over-using modules can make your overall OpenTofu | |
| configuration harder to understand and maintain, so we recommend moderation. | |
| A good module should raise the level of abstraction by describing a new concept | |
| in your architecture that is constructed from resource types offered by | |
| providers. | |
| For example, `aws_instance` and `aws_elb` are both resource types belonging to | |
| the AWS provider. You might use a module to represent the higher-level concept | |
| "[HashiCorp Consul](https://www.consul.io/) cluster running in AWS" which | |
| happens to be constructed from these and other AWS provider resources. | |
| We _do not_ recommend writing modules that are just thin wrappers around single | |
| other resource types. If you have trouble finding a name for your module that | |
| isn't the same as the main resource type inside it, that may be a sign that | |
| your module is not creating any new abstraction and so the module is | |
| adding unnecessary complexity. Just use the resource type directly in the | |
| calling module instead. | |
| ## Refactoring module resources | |
| You can include [refactoring blocks](../../../language/modules/develop/refactoring.mdx) to record how resource | |
| names and module structure have changed from previous module versions. | |
| OpenTofu uses that information during planning to reinterpret existing objects | |
| as if they had been created at the corresponding new addresses, eliminating a | |
| separate workflow step to replace or migrate existing objects. | |
| ## Building blocks of a module | |
| For a well-documented module that is ready to be published, there are some parts that the authors should take care of. | |
| ### Readme | |
| A root level README.md file should explain to users how the module should be used. | |
| This file will show up in the Registry Search if the license allows for it. | |
| ### License | |
| The module should be licensed under one of | |
| the [supported licenses](https://github.com/opentofu/registry-ui/blob/main/licenses.json). | |
| If the module is not under one of these licenses, it will be findable in the [Registry Search](https://search.opentofu.org/), | |
| but no other data will be displayed. | |
| ### Submodules | |
| A module can contain also submodules. To make the submodules show up in the Registry Search, | |
| place the submodules in the `modules/MODULENAME` directory in the module directory. | |
| Each submodule directory can contain a `README.md` file to provide more information about the submodule scope. | |
| ### Examples | |
| Similar in structure to submodules, examples provide users with an easy way to get into using the module. | |
| For an example to show up in the OpenTofu Registry Search, it needs to be placed into `examples/EXAMPLENAME` folder and | |
| be accompanied by a `README.md` file providing more information about the example. | |
| ### Testing the module | |
| Tests are a great way to ensure that the module stays working when community pull requests come in. | |
| The [`tofu test` command](../../../cli/commands/test/) has a host of tools that allow writing automated tests for | |
| the module. | |