github.com/muratcelep/terraform@v1.1.0-beta2-not-internal-4/website/docs/language/modules/develop/structure.html.md (about) 1 --- 2 layout: "language" 3 page_title: "Standard Module Structure" 4 --- 5 6 # Standard Module Structure 7 8 The standard module structure is a file and directory layout we recommend for 9 reusable modules distributed in separate repositories. Terraform tooling is 10 built to understand the standard module structure and use that structure to 11 generate documentation, index modules for the module registry, and more. 12 13 The standard module structure expects the layout documented below. The list may 14 appear long, but everything is optional except for the root module. Most modules 15 don't need to do any extra work to follow the standard structure. 16 17 * **Root module**. This is the **only required element** for the standard 18 module structure. Terraform files must exist in the root directory of 19 the repository. This should be the primary entrypoint for the module and is 20 expected to be opinionated. For the 21 [Consul module](https://registry.terraform.io/modules/hashicorp/consul) 22 the root module sets up a complete Consul cluster. It makes a lot of assumptions 23 however, and we expect that advanced users will use specific _nested modules_ 24 to more carefully control what they want. 25 26 * **README**. The root module and any nested modules should have README 27 files. This file should be named `README` or `README.md`. The latter will 28 be treated as markdown. There should be a description of the module and 29 what it should be used for. If you want to include an example for how this 30 module can be used in combination with other resources, put it in an [examples 31 directory like this](https://github.com/hashicorp/terraform-aws-consul/tree/master/examples). 32 Consider including a visual diagram depicting the infrastructure resources 33 the module may create and their relationship. 34 35 The README doesn't need to document inputs or outputs of the module because 36 tooling will automatically generate this. If you are linking to a file or 37 embedding an image contained in the repository itself, use a commit-specific 38 absolute URL so the link won't point to the wrong version of a resource in the 39 future. 40 41 * **LICENSE**. The license under which this module is available. If you are 42 publishing a module publicly, many organizations will not adopt a module 43 unless a clear license is present. We recommend always having a license 44 file, even if it is not an open source license. 45 46 * **`main.tf`, `variables.tf`, `outputs.tf`**. These are the recommended filenames for 47 a minimal module, even if they're empty. `main.tf` should be the primary 48 entrypoint. For a simple module, this may be where all the resources are 49 created. For a complex module, resource creation may be split into multiple 50 files but any nested module calls should be in the main file. `variables.tf` 51 and `outputs.tf` should contain the declarations for variables and outputs, 52 respectively. 53 54 * **Variables and outputs should have descriptions.** All variables and 55 outputs should have one or two sentence descriptions that explain their 56 purpose. This is used for documentation. See the documentation for 57 [variable configuration](/docs/language/values/variables.html) and 58 [output configuration](/docs/language/values/outputs.html) for more details. 59 60 * **Nested modules**. Nested modules should exist under the `modules/` 61 subdirectory. Any nested module with a `README.md` is considered usable 62 by an external user. If a README doesn't exist, it is considered for internal 63 use only. These are purely advisory; Terraform will not actively deny usage 64 of internal modules. Nested modules should be used to split complex behavior 65 into multiple small modules that advanced users can carefully pick and 66 choose. For example, the 67 [Consul module](https://registry.terraform.io/modules/hashicorp/consul) 68 has a nested module for creating the Cluster that is separate from the 69 module to setup necessary IAM policies. This allows a user to bring in their 70 own IAM policy choices. 71 72 If the root module includes calls to nested modules, they should use relative 73 paths like `./modules/consul-cluster` so that Terraform will consider them 74 to be part of the same repository or package, rather than downloading them 75 again separately. 76 77 If a repository or package contains multiple nested modules, they should 78 ideally be [composable](./composition.html) by the caller, rather than 79 calling directly to each other and creating a deeply-nested tree of modules. 80 81 * **Examples**. Examples of using the module should exist under the 82 `examples/` subdirectory at the root of the repository. Each example may have 83 a README to explain the goal and usage of the example. Examples for 84 submodules should also be placed in the root `examples/` directory. 85 86 Because examples will often be copied into other repositories for 87 customization, any `module` blocks should have their `source` set to the 88 address an external caller would use, not to a relative path. 89 90 A minimal recommended module following the standard structure is shown below. 91 While the root module is the only required element, we recommend the structure 92 below as the minimum: 93 94 ```sh 95 $ tree minimal-module/ 96 . 97 ├── README.md 98 ├── main.tf 99 ├── variables.tf 100 ├── outputs.tf 101 ``` 102 103 A complete example of a module following the standard structure is shown below. 104 This example includes all optional elements and is therefore the most 105 complex a module can become: 106 107 ```sh 108 $ tree complete-module/ 109 . 110 ├── README.md 111 ├── main.tf 112 ├── variables.tf 113 ├── outputs.tf 114 ├── ... 115 ├── modules/ 116 │ ├── nestedA/ 117 │ │ ├── README.md 118 │ │ ├── variables.tf 119 │ │ ├── main.tf 120 │ │ ├── outputs.tf 121 │ ├── nestedB/ 122 │ ├── .../ 123 ├── examples/ 124 │ ├── exampleA/ 125 │ │ ├── main.tf 126 │ ├── exampleB/ 127 │ ├── .../ 128 ```