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


