github.com/kcburge/terraform@v0.11.12-beta1/website/docs/modules/create.html.markdown (about) 1 --- 2 layout: "docs" 3 page_title: "Creating Modules" 4 sidebar_current: "docs-modules-create" 5 description: How to create modules. 6 --- 7 8 # Creating Modules 9 10 Creating modules in Terraform is easy. You may want to do this to better organize your code, to make a reusable component, or just to learn more about Terraform. For any reason, if you already know the basics of Terraform, then creating a module is a piece of cake. 11 12 Modules in Terraform are folders with Terraform files. In fact, when you run `terraform apply`, the current working directory holding 13 the Terraform files you're applying comprise what is called the _root module_. This itself is a valid module. 14 15 Therefore, you can enter the source of any module, satisfy any required variables, run `terraform apply`, and expect it to work. 16 17 Modules that are created for reuse should follow the 18 [standard structure](#standard-module-structure). This structure enables tooling 19 such as the [Terraform Registry](/docs/registry/index.html) to inspect and 20 generate documentation, read examples, and more. 21 22 ## An Example Module 23 24 Within a folder containing Terraform configurations, create a subfolder called `child`. In this subfolder, make one empty `main.tf` file. Then, back in the root folder containing the `child` folder, add this to one of your Terraform configuration files: 25 26 ```hcl 27 module "child" { 28 source = "./child" 29 } 30 ``` 31 32 You've now created your first module! You can now add resources to the `child` module. 33 34 **Note:** Prior to running the above, you'll have to run [the get command](/docs/commands/get.html) for Terraform to sync 35 your modules. This should be instant since the module is a local path. 36 37 ## Inputs/Outputs 38 39 To make modules more useful than simple isolated containers of Terraform configurations, modules can be configured and also have outputs that can be consumed by your Terraform configuration. 40 41 Inputs of a module are [variables](/docs/configuration/variables.html) and outputs are [outputs](/docs/configuration/outputs.html). There is no special syntax to define these, they're defined just like any other variables or outputs. You can think about these variables and outputs as the API interface to your module. 42 43 Let's add a variable and an output to our `child` module. 44 45 ```hcl 46 variable "memory" {} 47 48 output "received" { 49 value = "${var.memory}" 50 } 51 ``` 52 53 This will create a required variable, `memory`, and then an output, `received`, that will be the value of the `memory` variable. 54 55 You can then configure the module and use the output like so: 56 57 ```hcl 58 module "child" { 59 source = "./child" 60 61 memory = "1G" 62 } 63 64 output "child_memory" { 65 value = "${module.child.received}" 66 } 67 ``` 68 69 If you now run `terraform apply`, you see how this works. 70 71 ## Paths and Embedded Files 72 73 It is sometimes useful to embed files within the module that aren't Terraform configuration files, such as a script to provision a resource or a file to upload. 74 75 In these cases, you can't use a relative path, since paths in Terraform are generally relative to the working directory from which Terraform was executed. Instead, you want to use a module-relative path. To do this, you should use the [path interpolated variables](/docs/configuration/interpolation.html). 76 77 ```hcl 78 resource "aws_instance" "server" { 79 # ... 80 81 provisioner "remote-exec" { 82 script = "${path.module}/script.sh" 83 } 84 } 85 ``` 86 87 Here we use `${path.module}` to get a module-relative path. 88 89 ## Nested Modules 90 91 You can nest a module within another module. This module will be hidden from your root configuration, so you'll have to re-expose any 92 variables and outputs you require. 93 94 The [get command](/docs/commands/get.html) will automatically get all nested modules. 95 96 You don't have to worry about conflicting versions of modules, since Terraform builds isolated subtrees of all dependencies. For example, one module might use version 1.0 of module `foo` and another module might use version 2.0, and this will all work fine within Terraform since the modules are created separately. 97 98 ## Standard Module Structure 99 100 The standard module structure is a file and folder layout we recommend for 101 reusable modules. Terraform tooling is built to understand the standard 102 module structure and use that structure to generate documentation, index 103 modules for the registry, and more. 104 105 The standard module expects the structure documented below. The list may appear 106 long, but everything is optional except for the root module. All items are 107 documented in detail. Most modules don't need to do any work to follow the 108 standard structure. 109 110 * **Root module**. This is the **only required element** for the standard 111 module structure. Terraform files must exist in the root directory of 112 the module. This should be the primary entrypoint for the module and is 113 expected to be opinionated. For the 114 [Consul module](https://registry.terraform.io/modules/hashicorp/consul) 115 the root module sets up a complete Consul cluster. A lot of assumptions 116 are made, however, and it is fully expected that advanced users will use 117 specific nested modules to more carefully control what they want. 118 119 * **README**. The root module and any nested modules should have README 120 files. This file should be named `README` or `README.md`. The latter will 121 be treated as markdown. There should be a description of the module and 122 what it should be used for. If you want to include an example for how this 123 module can be used in combination with other resources, put it in an [examples 124 directory like this](https://github.com/hashicorp/terraform-aws-consul/tree/master/examples). 125 Consider including a visual diagram depicting the infrastructure resources 126 the module may create and their relationship. The README doesn't need to 127 document inputs or outputs of the module because tooling will automatically 128 generate this. If you are linking to a file or embedding an image contained 129 in the repository itself, use a commit-specific absolute URL so the link won't 130 point to the wrong version of a resource in the future. 131 132 * **LICENSE**. The license under which this module is available. If you are 133 publishing a module publicly, many organizations will not adopt a module 134 unless a clear license is present. We recommend always having a license 135 file, even if the license is non-public. 136 137 * **main.tf, variables.tf, outputs.tf**. These are the recommended filenames for 138 a minimal module, even if they're empty. `main.tf` should be the primary 139 entrypoint. For a simple module, this may be where all the resources are 140 created. For a complex module, resource creation may be split into multiple 141 files but all nested module usage should be in the main file. `variables.tf` 142 and `outputs.tf` should contain the declarations for variables and outputs, 143 respectively. 144 145 * **Variables and outputs should have descriptions.** All variables and 146 outputs should have one or two sentence descriptions that explain their 147 purpose. This is used for documentation. See the documentation for 148 [variable configuration](/docs/configuration/variables.html) and 149 [output configuration](/docs/configuration/outputs.html) for more details. 150 151 * **Nested modules**. Nested modules should exist under the `modules/` 152 subdirectory. Any nested module with a `README.md` is considered usable 153 by an external user. If a README doesn't exist, it is considered for internal 154 use only. These are purely advisory; Terraform will not actively deny usage 155 of internal modules. Nested modules should be used to split complex behavior 156 into multiple small modules that advanced users can carefully pick and 157 choose. For example, the 158 [Consul module](https://registry.terraform.io/modules/hashicorp/consul) 159 has a nested module for creating the Cluster that is separate from the 160 module to setup necessary IAM policies. This allows a user to bring in their 161 own IAM policy choices. 162 163 * **Examples**. Examples of using the module should exist under the 164 `examples/` subdirectory at the root of the repository. Each example may have 165 a README to explain the goal and usage of the example. Examples for 166 submodules should also be placed in the root `examples/` directory. 167 168 A minimal recommended module following the standard structure is shown below. 169 While the root module is the only required element, we recommend the structure 170 below as the minimum: 171 172 ```sh 173 $ tree minimal-module/ 174 . 175 ├── README.md 176 ├── main.tf 177 ├── variables.tf 178 ├── outputs.tf 179 ``` 180 181 A complete example of a module following the standard structure is shown below. 182 This example includes all optional elements and is therefore the most 183 complex a module can become: 184 185 ```sh 186 $ tree complete-module/ 187 . 188 ├── README.md 189 ├── main.tf 190 ├── variables.tf 191 ├── outputs.tf 192 ├── ... 193 ├── modules/ 194 │ ├── nestedA/ 195 │ │ ├── README.md 196 │ │ ├── variables.tf 197 │ │ ├── main.tf 198 │ │ ├── outputs.tf 199 │ ├── nestedB/ 200 │ ├── .../ 201 ├── examples/ 202 │ ├── exampleA/ 203 │ │ ├── main.tf 204 │ ├── exampleB/ 205 │ ├── .../ 206 ``` 207 208 ## Publishing Modules 209 210 If you've built a module that you intend to be reused, we recommend 211 [publishing the module](/docs/registry/modules/publish.html) on the 212 [Terraform Registry](https://registry.terraform.io). This will version 213 your module, generate documentation, and more. 214 215 Published modules can be easily consumed by Terraform, and (from Terraform 216 0.11) you can also [constrain module versions](usage.html#module-versions) for safe and predictable 217 updates. The following example shows how easy it is to consume a module 218 from the registry: 219 220 ```hcl 221 module "consul" { 222 source = "hashicorp/consul/aws" 223 } 224 ``` 225 226 You can also gain all the benefits of the registry for private modules 227 by signing up for a [private registry](/docs/registry/private.html).