96 lines
2.9 KiB
Markdown
96 lines
2.9 KiB
Markdown
|
---
|
||
|
layout: "docs"
|
||
|
page_title: "Creating Modules"
|
||
|
sidebar_current: "docs-modules-create"
|
||
|
---
|
||
|
|
||
|
# Creating Modules
|
||
|
|
||
|
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,
|
||
|
creating a module is a piece of cake.
|
||
|
|
||
|
Modules in Terraform are just folders with Terraform files. In fact,
|
||
|
when you run `terraform apply`, the current working directory holding
|
||
|
the Terraform files you're applying comprise what is called the
|
||
|
_root module_. It itself is a valid module.
|
||
|
|
||
|
Therefore, you can enter the source of any module, run `terraform apply`,
|
||
|
and expect it to work (assuming you satisfy the required variables, if any).
|
||
|
|
||
|
## An Example
|
||
|
|
||
|
Within a folder containing Terraform configurations, create a subfolder
|
||
|
"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 the
|
||
|
Terraform files:
|
||
|
|
||
|
```
|
||
|
module "child" {
|
||
|
source = "./child"
|
||
|
}
|
||
|
```
|
||
|
|
||
|
This will work. You've created your first module! You can add resources
|
||
|
to the child module to see how that interaction works.
|
||
|
|
||
|
## Inputs/Outputs
|
||
|
|
||
|
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 the configuration using the module.
|
||
|
|
||
|
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.
|
||
|
|
||
|
In the "child" module we created above, add the following:
|
||
|
|
||
|
```
|
||
|
variable "memory" {}
|
||
|
|
||
|
output "received" {
|
||
|
value = "${var.memory}"
|
||
|
}
|
||
|
```
|
||
|
|
||
|
This will create a required variable "memory" and then an output "received"
|
||
|
that will simply be the value of the memory variable.
|
||
|
|
||
|
You can then configure the module and use the output like so:
|
||
|
|
||
|
```
|
||
|
module "child" {
|
||
|
source = "./child"
|
||
|
|
||
|
memory = "1G"
|
||
|
}
|
||
|
|
||
|
output "child_memory" {
|
||
|
value = "${module.child.received}"
|
||
|
}
|
||
|
```
|
||
|
|
||
|
If you run `apply`, you'll again see that this works.
|
||
|
|
||
|
And that is all there is to it. Variables and outputs are used to configure
|
||
|
modules and provide results. Resources within a module are isolated,
|
||
|
and the whole thing is managed as a single unit.
|
||
|
|
||
|
## Nested Modules
|
||
|
|
||
|
You can use a module within a module just like you would anywhere else.
|
||
|
This module will be hidden from the root user, so you'll have re-expose any
|
||
|
variables if you need to, as well as outputs.
|
||
|
|
||
|
The [get command](/docs/commands/get.html) will automatically get all
|
||
|
nested modules as well.
|
||
|
|
||
|
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 of module "foo", and this would all work fine
|
||
|
within Terraform since the modules are created separately.
|